| 对比 | password | token |
|---|---|---|
| 时效性 | 时效性更长 | 具有时效限 |
| 权限范围 | 完整权限 | 有限权限 |
应用场景
- 只有客户端,没有自己的服务器,没有认证/授权服务器
- 只有前端,直接获取token,没有获取授权码这个中间步骤
- 用于安全要求低的场景,令牌的有效期必须非常短,通常就是session期间有效(浏览器关闭,令牌失效)
业务流程:
- 申请客户端唯一标识:向服务提供商备案,获取clientID和clientSecret
- 获取token:直接要求返回令牌response_type=token
请求:https://b.com/oauth/authorize?response_type=token&client_id=CLIENT_ID&redirect_uri=a.com&scope=read 响应:https://a.com/callback#token=ACCESS_TOKEN 重定向到到a.com,在锚点后面添加ACCESS_TOKEN
为什么需要申请clientID和clientSecret?
答:HTTP是无状态协议,需要唯一标识客户端
为什么ACCESS_TOKEN要放到锚点后面?
答:OAuth2.0允许HTTP协议网址跳转,HTTP协议跳转存在中间人攻击风险。浏览器跳转时,锚点不会发到服务器
应用场景
- 使用同一套认证授权服务器,不同的产品线
- 高度信任某个应用,允许用户直接把用户名和密码告诉该应用。应用使用用户名和密码去申请令牌
业务流程:
- 申请客户端唯一标识:向服务提供商备案,获取clientID和clientSecret
- 获取token:使用用户名和密码获取token grant_type=password
请求:https://oauth.b.com/token?grant_type=password&username=USERNAME&password=PASSWORD&client_id=CLIENT_ID 响应:token四种模式/客户端模式
应用场景
- 信任度比密码模式更高,服务A要访问服务B,服务A找认证服务器直接获取token
业务流程:
- 申请客户端唯一标识:向服务提供商备案,获取clientID和clientSecret
- 获取token:使用客户端ID和客户端密码获取token grant_type=client_credentials
请求:https://oauth.b.com/token?grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET 响应:token四种模式/授权码模式 总结
URL总结:你是谁、你要什么、我怎么给你、范围
保存位置总结:
- 服务端:token,refresh token,client id,client secret
- 客户端:授权码
开发流程总结:先开发认证授权服务,再开发资源服务
四种角色总结:
- 用户
- 用户代理、第三方
- 认证服务器
- 资源服务器
应用场景:
- 没有信任,有后端,有认证服务,资源服务,适合分布式环境
授权码模式为什么安全?
答:授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成
业务流程:先获取授权码,再用授权码获取令牌
- 豆瓣对接QQ开放平台:获取clientId(appId)和clientSecret(appSecret)唯一标识豆瓣
- 豆瓣用户登录:选择QQ登录方式
- QQ用户登录:获取授权码时用户未登录QQ,会跳转到QQ登录界面,登录QQ成功之后,跳到授权界面
https://graph.qq.com/oauth2.0/show ?which=Login&display=pc &scope=get_user_info &state=X-ZRbHUcfMs%2523movie%2523https%253A%2F%2Fmovie.douban.com%2F &redirect_uri=https%3A%2F%2Faccounts.douban.com%2Fconnect%2Fqq%2Fcallback &response_type=code &client_id=100387276
- 用户点击授权:站在QQ角度,豆瓣就是第三方应用
先获取授权码 response_type=code再根据授权码获取token grant_type=authorization_code
数据库:
表oauth_client_details,设置客户端唯一标识,字段client_id、client_secret 表oauth_client_details,设置授权码重定向地址,字段web_server_redirect_uri
URL
# 先获取授权码 response_type=code http://authServerIP:8082/oauth/authorize?client_id=clientID&response_type=code http://authServerIP:8082/login http://authServerIP:8082/oauth/authorize?client_id=client&response_type=code baidu.com/?code=uHhvhx # 再根据授权码获取token grant_type=authorization_code http://clientId:clientSecret@authServerIP:8082/oauth/token?grant_type=authorization_code&code=uHhvhx # 根据token获取资源 http://resourceServerIP:8080/resourcePath?ACCESS_TOKEN # 校验token http://authServerIP:8082/oauth/check_token?ACCESS_TOKEN
- 申请客户端唯一标识:向服务提供商备案,获取clientID和clientSecret
在数据库表oauth_client_details 设置字段client_id、client_secret的值 - 请求获取授权码:打开浏览器输入地址
请求:http://authServerIP:8082/oauth/authorize?client_id=clientID&response_type=code - 第一次访问会重定向到登录页面:获取授权码时用户未登录,跳转到登录界面
重定向:http://authServerIP:8082/login
- 重定向到授权页面:登录成功后跳转到授权页面
重定向:http://authServerIP:8082/oauth/authorize?client_id=client&response_type=code
- 重定向返回授权码:重定向到oauth_client_details表字段web_server_redirect_uri,返回授权码
重定向:baidu.com/?code=uHhvhx - 通过授权码获取token
请求:http://clientId:clientSecret@authServerIP:8082/oauth/token?grant_type=authorization_code&code=uHhvhx
响应:{ "access_token": "d31e2340-a3fb-4b29-9479-e46c1da971b2", "token_type": "bearer", "expires_in": 43199, "scope": "trust read write" } - 访问资源:用户代理访问资源服务器
请求:http://resourceServerIP:8080/resourcePath?ACCESS_TOKEN
响应:资源 - 校验token:资源服务器访问认证服务器
请求:http://authServerIP:8082/oauth/check_token?ACCESS_TOKEN
处理:认证服务器检查通过-资源服务器才将资源返回给资源拥有者。
响应:校验通过/不通过 - 响应资源:资源服务器响应资源给用户代理



