技术分享
数据库连接池
Vue双向数据绑定
访问授权协议-OAuth2
Golang 基础赋能(一)
Golang基础赋能(二)
-
+
首页
访问授权协议-OAuth2
## 什么是OAuth2协议? ``` 互联网上的一款安全协议 OAuth协议为用户资源的授权提供了一个安全的、开放而又简易的标准。 OAuth主要有OAuth1.0a和OAuth2.0两个版本,并且二者完全不同,且不兼容。OAuth2.0是目前是市面上最广泛使用的版本 ``` 如下图所示,第三方登录就是Oauth2的一种应用场景 ![](https://static.cloudcare.cn/cloudcare-mrdoc/img/2024-08-27_140516_0554090.614429854654696.png) ## 为什么要有OAuth2? 随着时代的发展,对于企业而言,可能会遇到下面这些问题 - 不同服务之间的分别部署,用户的登录问题,如果让用户在不同服务上注册账号密码,过于麻烦 - 第三方程序接入提供信息的问题,如何确定授权范围(授权的范围) - 如果选择将用户账号密码暴露给第三方或不同服务,如何解决用户修改账号密码授权失效的问题 …… 为了解决上面的问题,OAuth2诞生了 ## OAuth2的四种授权模式 ### 授权码模式 授权码模式(authorization code)是功能最完整、流程最严密的授权模式。它的特点就是通过客户端的后台服务器,与”服务提供商”的认证服务器进行互动。分为下述步骤: ``` (A)用户访问客户端,后者将前者导向认证服务器。 (B)用户选择是否给予客户端授权。 (C)假设用户给予授权,认证服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码。 (D)客户端收到授权码,附上早先的"重定向URI",向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。 (E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。 ``` 授权码模式是最繁琐的模式,也是安全系数最高的模式,因此市面上最常见的就是该模式` ### 简化模式(隐式授权) 简化模式(implicit grant type)不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了"授权码"这个步骤,因此得名。所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证。分为下述步骤: ``` (A)客户端将用户导向认证服务器。 (B)用户决定是否给于客户端授权。 (C)假设用户给予授权,认证服务器将用户导向客户端指定的"重定向URI",并在URI的Hash部分包含了访问令牌。 (D)浏览器向资源服务器发出请求,其中不包括上一步收到的Hash值。 (E)资源服务器返回一个网页,其中包含的代码可以获取Hash值中的令牌。 (F)浏览器执行上一步获得的脚本,提取出令牌。 (G)浏览器将令牌发给客户端。 ``` 简化模式一般用于没有后端应用的时候,常见于第三方单页面应用。例如调查问卷等 ### 密码模式(**资源所有者密码凭证**) 密码模式(Resource Owner Password Credentials Grant)中,用户向客户端提供自己的用户名和密码。客户端使用这些信息,向"服务商提供商"索要授权。分为下述步骤: ``` (A)用户向客户端提供用户名和密码。 (B)客户端将用户名和密码发给认证服务器,向后者请求令牌。 (C)认证服务器确认无误后,向客户端提供访问令牌。 ``` ### 客户端模式(客户端凭证) 客户端模式(Client Credentials Grant)指客户端以自己的名义,而不是以用户的名义,向"服务提供商"进行认证。严格地说,客户端模式并不属于OAuth框架所要解决的问题。在这种模式中,用户直接向客户端注册,客户端以自己的名义要求"服务提供商"提供服务,其实不存在授权问题。分为下述步骤: ``` (A)客户端向认证服务器进行身份认证,并要求一个访问令牌。 (B)认证服务器确认无误后,向客户端提供访问令牌。 ``` ### 授权模式类比 | 授权模式 | 优点 | 缺点 | 应用场景 | | ---------- | ------------------------------------------ | -------------------------------------------------- | ------------------------------------------------------------ | | 授权码模式 | 安全性较高<br />功能最完整<br />流程最严密 | 需要额外的交互步骤<br />客户端需要存储和管理授权码 | 适用于有自己的服务器的应用<br />例如公网的开放平台 | | 简化模式 | 流程简单 | 安全性较低<br />访问令牌容易泄露且不可刷新 | 适用于无后端服务的纯前端应用<br />例如纯静态页面应用 | | 密码模式 | 简单易用<br />无额外的交互步骤 | 安全性较低<br />用户的账号和密码直接暴露给客户端 | 资源所有者与客户端具有良好信任关系的场景<br />例如客户端是设备的操作系统或具备高权限的应用 | | 客户端模式 | 简单易用 | 安全性较低<br />不涉及用户的身份验证 | 适用于客户端需要访问自己拥有的资源的场景<br />例如移动应用访问自己的后台服务器 ,或者在微服务架构中服务之间的调用 | ## OAuth2实际应用:如何实现微信第三方登录 > 授权码模式 ### 1.注册应用 在https://open.weixin.qq.com/网站注册应用,以获取app_id以及app_secret ### 2.前端接收code **流程** 1)用户点击页面上的第三方登录,拼接好对应的路由,并在浏览器中打开 拼接的路由结构如下 https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect **参数说明** | 参数 | 是否必须 | 说明 | | :------------ | :------- | :----------------------------------------------------------- | | appid | 是 | 应用唯一标识(前面认证网页应用中获得) | | redirect_uri | 是 | 重定向地址,需要进行UrlEncode(前面认证网页应用中获得) | | response_type | 是 | 填code | | scope | 是 | 应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即可 | | state | 否 | 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验 | 2.用户进行扫描,微信会进行验证,并返回到回调的url上,所以前端要监听对应的回调地址,判断微信是否返回 3.接受微信返回的code,并发送给后端 ### 3.后端接受凭证并通过code获取access_token **流程** 1)后端拼接路由并发送请求 路由结构如下 https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code **参数说明** | 参数 | 是否必须 | 说明 | | :--------- | :------- | :------------------------------------------------------ | | appid | 是 | 应用唯一标识,在微信开放平台提交应用审核通过后获得 | | secret | 是 | 应用密钥AppSecret,在微信开放平台提交应用审核通过后获得 | | code | 是 | 填写第一步获取的code参数 | | grant_type | 是 | 填authorization_code | 2)接收微信返回的信息 ex: ``` { "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE", "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" } ``` **参数说明** | 参数 | 说明 | | :------------ | :----------------------------------------------------------- | | access_token | 接口调用凭证 | | expires_in | access_token接口调用凭证超时时间,单位(秒) | | refresh_token | 用户刷新access_token | | openid | 授权用户唯一标识 | | scope | 用户授权的作用域,使用逗号(,)分隔 | | unionid | 当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段。 | ### 4.通过access_token获取用户信息 **流程** 1)拼接路由并发送请求 https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID **参数说明** | 参数 | 是否必须 | 说明 | | :----------- | :------- | :----------------------------------------------------------- | | access_token | 是 | 调用凭证(上一个请求中获得) | | openid | 是 | 普通用户的标识,对当前开发者帐号唯一(上一个请求中获得) | | lang | 否 | 国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语,默认为zh-CN | 2)接收返回信息 ``` { "openid":"OPENID", "nickname":"NICKNAME", "sex":1, "province":"PROVINCE", "city":"CITY", "country":"COUNTRY", "headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0", "privilege":[ "PRIVILEGE1", "PRIVILEGE2" ], "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL" } ``` **参数说明** | 参数 | 说明 | | :--------- | :----------------------------------------------------------- | | openid | 普通用户的标识,对当前开发者帐号唯一 | | nickname | 普通用户昵称 | | sex | 普通用户性别,1为男性,2为女性 | | province | 普通用户个人资料填写的省份 | | city | 普通用户个人资料填写的城市 | | country | 国家,如中国为CN | | headimgurl | 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空 | | privilege | 用户特权信息,json数组,如微信沃卡用户为(chinaunicom) | | unionid | 用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。 |
吴晓俊
2024年8月27日 14:16
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码