授权码模式 (Authorization Code) 是最常见的 OAuth 授权类型;
它的流程相对于其他模式是最复杂也是最完善的;
我们这里还以 白俊遥博客 和 github 做示例;
拼接链接
获取 code 需要拼接一个链接;
这个过程是在第三方客户端完成的即 白俊遥博客;
在白俊遥博客上有一个 github 登陆按钮;
放在按钮上我们可以看到链接是: https://baijunyao.com/auth/oauth/redirectToProvider/github ;
当访问这个链接的时候 白俊遥博客 会跳转到 https://github.com/login/oauth/authorize ;
请求方式: GET
请求链接: https://github.com/login/oauth/authorize
并拼接携带如下参数:
response_type: code
client_id: xxx
redirect_uri: https://baijunyao.com/auth/oauth/handleProviderCallback/github
scope: user:email
state: xxx
response_type 固定参数这里就是 code ;
client_id 是白俊遥博客在 github 上申请的;
redirect_uri 是当在 github 授权后会跳回来的链接;
scope 要申请的权限;
state 白俊遥博客随机生成的一个字符串是为了安全;
完整的链接就是这样的: https://github.com/login/oauth/authorize?client_id=xxx&redirect_uri=https%3A%2F%2Fbaijunyao.com%2Fauth%2Foauth%2FhandleProviderCallback%2Fgithub&scope=user%3Aemail&response_type=code&state=xxx
获取 code
上一步我们跳转到了 https://github.com/login/oauth/authorize ;
到 github 后会先判断是否已经登录;
如果没有登录则会显示登录的页面;
请注意这里的链接是 github 的;
页面也是 github 的;
也就是说这个过程输入的账号密码 白俊遥博客 是获取不到的;
当登录后会跳转到授权页面;
要获取的权限就是上一步中的 scope 的值即 user:email;
当用户点击授权按钮后就会跳转回到上一步中的 redirect_uri ;
请求方式: GET
请求链接: https://baijunyao.com/auth/oauth/handleProviderCallback/github
并携带如下参数:
code: xxx
state: xxx
code 是用来在下一步获取 token ;
state 是上一步生成的随机字符;
获取 token
现在 白俊遥博客 已经拿到了 code ;
接着在 白俊遥博客 服务器上会向 github 发一个获取用户信息的请求;
请求方式: POST
链接: https://github.com/login/oauth/access_token ;
请求参数如下:
grant_type: authorization_code
code: xxx
client_id: xxx
client_secret: xxx
redirect_uri: https//baijunyao.com/auth/oauth/handleProviderCallback/github
state: xxx
grant_type 固定值为 authorization_code
code 是上一步获取到的 code ;
client_id 是白俊遥博客在 github 上申请的;
client_secret 是白俊遥博客在 github 上申请的;
redirect_uri 跟第一步拼接链接中的 redirect_uri 一致;
state 是之前生成的随机字符;
此请求的返回值如下:
{
"token_type": "Bearer",
"expires_in": xxx,
"access_token": "xxx",
"refresh_token": "xxx",
}
token_type 是 token 类型一般是 Bearer ;
expires_in 过期时间
access_token 用于访问资源的令牌
refresh_token 用于刷新 access_token
刷新 token
当 access_token 过期后我们可以使用 refresh_token 获取新的 access_token ;
刷新 access_token 的方式如下:
请求类型: POST
请求链接: https://github.com/login/oauth/refresh_token ;
请求参数如下:
grant_type: refresh_token
refresh_token: xxx
scope: user:email
刷新 token 的返回值跟获取 token 步骤中的返回值一样;
至此完整的授权码模式流程就完成了;
我们最终拿到了 access_token ;
access_token 就如同用户的账号密码;
白俊遥博客 拿着 access_token 就可以去 github 获取用户的信息;
而这整个过程中用户并没有把账号密码给 白俊遥博客;
而且 白俊遥博客 只能获取经过授权的用户信息数据;
完全满足我们上篇文章 OAuth 系列(一)序言 中的各种需求;
OAuth 是一项协议;
各个平台实现的方式不完全相同;
这里只是以 github 举例;
为了跟 OAuth 官方的协议保持一致;
上面示例中的一些返回值跟实际的 github 文档中的并不完全相同;