当前位置: 首页 > 科技观察

一口气说出OAuth2.0的四种授权方式

时间:2023-03-14 16:37:13 科技观察

转载本文请联系程序员内电师公众号。上周,我自研的开源项目开始破土,《开源项目迈出第一步,10 选 1?页面模板成了第一个绊脚石 》,花了很长时间才付诸实施。这样做的初衷,并不是为了让自己太稳。技术之路不进步,等于退却。你必须强迫自己学习。项目偏向于技术实践,所以不会有过多的业务堆叠。最好在公司学习业务代码。现在我在做技术选型和储备,像比较主流的,项目前后端分离,微服务,Springboot,Springcloud等都会应用到项目中。其实很多技术我都不懂。提高技术的过程真的比打工快多了。毕竟,主动学习和被动学习有着本质的区别。这几天打算完成项目前后端分离架构的搭建。既然是前后端分离的项目,认证是不可避免的,所以oauth2.0是我们不得不了解的一个知识点。一、什么是OAuth2.0简单理解OAuth是一种授权机制,它是客户端和资源拥有者之间的授权层,用来分隔两个不同的角色。资源所有者同意并向客户端颁发令牌后,客户端可以使用令牌访问资源所有者的资源。OAuth2.0是OAuth协议的一个版本。如果有2.0版本,就会有1.0版本。有意思的是,OAuth2.0并不向后兼容OAuth1.0,相当于放弃了1.0版本。举个小栗子解释一下什么是OAuth授权?我在家饿了就点了外卖。外卖小哥30秒就到了楼下。但是,有一个门控阻止我进入。可以输入密码进入,但是出于安全考虑我不想告诉他密码。这时,外卖小哥看到门禁中多了一个高级按钮“一键授权”。只要我同意,他就会得到一个令牌(token),有效期为2小时,可以正常进出。令牌(token)和密码虽然功能相似,都可以进入系统,但是还是有一些区别的。令牌有权限范围,时效性,自动失效,修改无效。2、OAuth2.0授权方式OAuth2.0授权简单理解其实就是获取token的过程。OAuth协议定义了四种获取令牌(authorizationgrant)的授权方式如下:我们使用,三方应用在申请token之前,必须先申请一个在系统中唯一的身份标识:客户端ID(clientID)和客户端密钥(clientsecret)。这样做可以确保令牌不会被恶意使用。下面我们就来分析一下每种授权方式的原理。在进入正题之前,我们首先要了解OAuth2.0授权过程中的几个重要参数:response_type:code表示需要返回授权码,token表示直接返回tokenclient_id:客户端身份标识client_secret:客户端keyredirect_uri:重定向地址scope:表示授权范围,read只读权限,所有读写权限grant_type:表示授权方式,AUTHORIZATION_CODE(授权码),password(密码),client_credentials(证书类型),refresh_token更新令牌状态:应用程序传递的一个随机数,用于防止CSRF攻击。1、授权码授权码方式是OAuth2.0授权的四种方式中最复杂的一种,但也是最安全、最常用的方式。这种方式适用于前后台都有的web项目,因为有些项目只有后台或者只有前端,授权码模式不适用。下图中,我们以WX登录掘金为例,详细看一下授权码方式的整体流程。用户选择WX登录掘金,掘金会向WX发起授权请求,WX会询问用户是否同意授权(常见弹窗授权)。response_type为code,需要返回授权码。scope参数表示授权范围为只读,redirect_uri表示重定向地址。https://wx.com/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=http://juejin.im/callback&scope=read用户同意授权后,WX会根据redirect_uri重定向,并带上授权码。http://juejin.im/callback?code=AUTHORIZATION_CODE掘金拿到授权码(code)后,带着授权码和key等参数向WX申请token。grant_type表示本次授权为授权码authorization_code,获取token需要客户端密钥client_secret和上一步获取的授权码code。https://wx.com/oauth/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=http://juejin.im/callback最后WX收到请求后向redirect_uri地址发送JSON数据,access_token为令牌。{"access_token":"ACCESS_TOKEN","token_type":"bearer","expires_in":2592000,"refresh_token":"REFRESH_TOKEN","scope":"read",...2.隐藏顶部提到有些Web应用没有后台,是纯前端应用,所以不能使用上面的授权码方式。token的申请和存储都需要在前端完成,跳过授权码这一步。前端应用直接获取token,response_type设置为token,要求直接返回token,跳过授权码,WX授权通过后重定向到指定的redirect_uri。https://wx.com/oauth/authorize?response_type=token&client_id=CLIENT_ID&redirect_uri=http://juejin.im/callback&scope=read3.密码密码方式比较容易理解。用户直接在掘金中输入自己的WX用户名和密码,掘金直接带着信息去WX申请token,并在请求响应的JSON结果中返回token。grant_typeispassword表示密码授权。https://wx.com/token?grant_type=password&username=USERNAME&password=PASSWORD&client_id=CLIENT_ID这种授权方式的缺点很明显,也很危险。如果使用此方法进行授权,则应用程序必须高度可信。4.凭证类型凭证类型与密码类型非常相似。主要适用于那些没有前端的命令行应用。可以通过最简单的方式获取token,在请求响应的JSON结果中返回token。grant_type为client_credentials表示凭据授权,client_id和client_secret用于标识身份。https://wx.com/token?grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET三、令牌的使用和更新1、如何使用令牌?拿到token后就可以调用WXAPI请求数据了,那么token怎么用呢?每次对WX的请求都必须带上token,把token放在http请求头的Authorization字段中。如果使用postman模拟请求,则需要将token放在Authorization->BearerToken中。注意:低版本的postman没有这个选项。2、token过期了怎么办?令牌是时间敏感的。一旦过期,需要重新获取。但是,重新走一遍授权流程,不仅麻烦,而且用户体验也不好。那么如何让令牌更新更优雅呢?一般在发行令牌时,一次发行两个令牌,一个令牌用于请求API,另一个负责更新令牌refresh_token。其中grant_type为refresh_token,request为refreshtoken,参数refresh_token为用于刷新token的token。https://wx.com/oauth/token?grant_type=refresh_token&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&refresh_token=REFRESH_TOKEN总结OAuth2.0授权其实难度不大,只是授权流程有点繁琐,逻辑有些绕。OAuth2.0是面试中经常被问到的知识点,应该多学习。原文链接:https://mp.weixin.qq.com/s/in_E1pKqQc8wkPXT61g8gQ