优秀的编程知识分享平台

网站首页 > 技术文章 正文

5分钟彻底搞懂"OAuth2.0"协议

nanyue 2024-08-08 18:59:32 技术文章 11 ℃


【写在最前】
我们在平时的API接口开发(比如微信公众号二次开发)中,经常会接触到“ OAuth2.0 ”这个概念,
但是很多小白总是搞不清楚code,state,access_token,refresh这些内部概念及其设计原理,甚至是在查阅了很多资料之后仍然是云山雾罩。
通过本文知识,让我们花5分钟时间彻底搞懂它,相信聪明的你,看完一定会有收获!


# 从一个典型的需求应用场景谈起:


一个游戏用户刚刚接触到一款新游戏,

但是他不想重新走游戏注册流程(性别,地区,手机,实名认证等一系列令人头大的繁琐动作),而是希望能用自己现成的微信账号直接登录游戏。


OAuth2.0,量身打造,专为授权而生。
注: OAuth2.0 是革命性版本,跟 OAuth1.0没一毛钱关系

# OAuth2.0 解决方案



解决方案原理:
OAuth2.0 在游戏服务器 与 微信认证服务器之间设置了一个授权层。
游戏客户端 不能直接登录微信认证服务器,只能登录授权层。正是借助这个中间层,微信认证服务器才可以将"游戏用户的手动授权请求 和 游戏客户端的普通程序请求区分开来”。
用户手动(主观)同意授权以后,微信认证服务器会下发一个带有“权限范围和有效期”的令牌,同时向游戏服务器开放微信认用户信息服务器的用户微信用户信息。

注1:认证服务器 和 用户信息服务器可以是同一个,也可以不是同一个(比如:用户信息服务器除了用户名和密码,还会提供更详细的性别,头像等更多用户信息)
注2:游戏服务器IP本身需要在微信认证服务器上提前注册(即白名单)。


OAuth2.0有多种授权模式,其中: 授权码模式是最完整、流程最严密的模式(也是微信二次开发的现行模式,即: response_type=code)


授权码模式完整流程,共分为 6 步:
Step1: 用户访问游戏客户端时,游戏客户端通过一个授权URL把用户导向微信认证服务器,微信认证服务器会返回一个授权页面,询问用户是否同意授权?

一个请求示例:GET /authorize?response_type=code&client_id=xxx&state=xyz&redirect_uri=https://xxx

请求参数释义:
response_type :表示授权类型,必选项,此处固定为”code”
client_id :表示游戏客户端的ID,必选项
redirect_uri :表示重定向URI,可选项
scope :表示申请的权限范围,可选项
state :表示游戏客户端的当前状态,可以指定任意值,微信认证服务器会原封不动地返回这个值


Step2: 用户点击“同意”按钮,在微信认证服务器登陆授权。
Step3: 微信认证服务器将用户导向A步骤指定的“重定向U”,同时附上一个授权码(code)。
请求参数释义:
code:表示授权码,必选项,该码跟client_id 和 redirect_uri 是一一对应关系。该码的有效期应该很短(通常设为10分钟),且只能使用该码一次,否则会被微信认证服务器拒绝。
state:如果游戏客户端的请求中包含这个参数,微信认证服务器的回应也必须一模一样包含这个参数。

Step4: 游戏服务器收到授权码,同时携带"重定向URI",向微信认证服务器申请令牌。
特别注意:这一步是在游戏务器上完成的,对用户和游戏客户端都不可见。
请求参数释义:
grant_type:表示使用的授权模式,必选项,此处固定为”authorization_code”。
code:表示上一步获得的授权码,必选项。
redirect_uri:表示重定向URI,必选项,且必须与A步骤中的该参数值保持一致。
client_id:表示游戏客户端ID,必选项。
Step5: 微信认证服务器核对授权码(code)和"重定向U",确认无误后向游戏服务器发送访问令牌(access_token)和更新令牌(refresh token)。
微信认证服务器发送的HTTP回复包含以下参数:
access_token:表示访问令牌(access_token),必选项。
refresh_token:表示更新令牌,用来获取下一次的访问令牌(access_token),可选项。
expires_in:表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。

Step6: 游戏服务器拿着获取的 访问令牌(access_token),调用指定API即可获取微信的用户信息(openid,unionid,avatar头像等)
上面六个步骤之中,Step2 是最关键的一步。
因为只有用户手动(主观)同意了这个授权,游戏客户端才可以获取令牌,进而凭令牌获取微信用户信息。


# 常见问题汇总


1)令牌过期了怎么办?
为了保证安全性,授权的令牌时间不可过长,但是一些游戏服务器需要长时间保持微信用户信息访问状态,
为此,OAuth 2.0 提供了更新令牌机制,一方面使令牌授权时间不会过长,另一方面保证了游戏服务器访问微信用户信息的连贯性。


2)为什么要先返回认证码(code)而不是直接返回令牌?
浏览器是一个不安全的环境,所以在用户给予授权后,微信认证服务器不是直接返回访问令牌(access_token),而是返回认证码(code),并通过浏览器重定向给游戏服务器。
游戏服务器需要先用认证码(code)换取访问令牌(access_token),而换取步骤需要微信认证服务器认证游戏服务器的身份(而不是验证浏览器身份),以此保证授权过程的安全性。

3)state 参数有什么用?
获取认证码(code)请求中,加入state参数可有效防止CSRF攻击。
CSRF攻击者要想诱导用户授权并插入自己的认证码(code),且被游戏服务器接收,就需要猜出该state参数,这大大增加了CSRF攻击的难度。


【全文完】
----------------------------------------
十年技术沉淀,只做原创文章;
及时关注作者,成就大牛之路!

Tags:

最近发表
标签列表