OAuth2.0 - 初入探究

前言


本周文章选题为 探究 RFC-6749 : OAuth2.0。

本文将会介绍

  • OAuth2.0中的相关要点
  • OAuth2.0的4种许可模式

OAuth2.0 相关要点


OAuth2.0的作用

(摘自维基百科)

OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。

OAuth2.0 中的角色

  • 资源所有者: 就是用户本人(假设这个资源是那个用户的)
  • 资源服务器: 可以获取资源的服务器
  • 客户端: 为 资源所有者 发起访问资源的应用程序,就是 申请授权的应用
  • 授权服务器: 用于授权的服务器....(可以与资源服务器是同一服务器)

OAuth2.0 基本流程

  1. 用户允许 第三方授权 (例如用户想用QQ 登录 简书)
  2. 然后用不同的模式获取到 access_token (如前言所说,有4个方法)
  3. 用access_token 去访问 开放的接口
  4. access_token如果过期了,就用refresh_token去更新token

OAuth2.0 的四种许可模式

假设端点地址:

  • 客户端回调地址: client.auth.com/cb
  • 授权端点地址: server.auth.com/authorize
  • 令牌端点地址: server.auth.com/token

模式一: 授权码模式


个人觉得用的最多的模式,微信,QQ都是用这个模式

基本步骤
  1. 客户端 携带自己的参数(response_type,客户端标识、请求范围、state和重定向URI)跳转访问 授权端点
  2. 授权端点返回302跳转, 带着 code 和 state 跳转到 重定向端点(重定向URI)
  3. 重定向端点 拿着参数(grant_type,code,重定向URI) 令牌端点 发起获取token请求
  4. 令牌端点 返回token
详细步骤

步骤一: 客户端 跳转访问 授权端点(其实就是页面跳转而已- -)
带上参数 跳转至 授权端点
http://server.auth.com/authorize?response_type=code&client_id=asdewq&state=asd&scope=all

参数项 说明 是否必须
response_type 请求类型,固定值:"code"
client_id 客户端ID,就是前面说的在注册时拿到的client_id
redirect_uri 重定向端点,如果注册时提交了就不需要了 ×
scope 授权范围,自定义字符串 ×
state 状态值,用来进行 跨站请求伪造(CSRF)保护,随意字符串 ×

** 此时用户应该在这里进行登陆操作!!!**
** 登陆成功后进行下面的返回 **

正常返回: code=授权码,state=之前提交的state,一模一样的返回

HTTP/1.1 302 Found
Location: https://client.auth.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=qwe

错误响应:有点复杂

HTTP/1.1 302 Found
Location: https://client.auth.com/cb?error=access_denied&state=qwe
参数项 说明 是否必须
error 请求类型,ASCII固定值
invalid_request:请求缺少必需的参数、包含无效的参数值、包含一个参数超过一次或其他不良格式
unauthorized_client:客户端未被授权使用此方法请求授权码。
access_denied:资源所有者或授权服务器拒绝该请求。
unsupported_response_type:授权服务器不支持使用此方法获得授权码。
invalid_scope:请求的范围无效,未知的或格式不正确。
server_error:授权服务器遇到意外情况导致其无法执行该请求。
temporarily_unavailable:授权服务器由于暂时超载或服务器维护目前无法处理请求。
error_description 错误描述,详细的描述,没有也可以 ×
error_uri 查看错误详细的地址 ×
state 之前传过来的state,如果有,一定要返回 ×/√

**步骤二: 跳转到 重定向端点 **
因为步骤一中,完成登陆验证之后,应该跳转到 重定向端点 .....(恩...就是这样)

**步骤三: 请求token **(有一点要注意,协议中规定token的传输,应该使用TLS来传输)
步骤二中跳转过来时,应该拿着code去兑换token,这步是由客户端的后台操作,在前端页面是不知道的
发送如下POST请求,到令牌端点:

POST /token HTTP/1.1
Host: server.auth.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
参数项 说明 是否必须
grant_type 授权类型,固定值:"authorization_code"
code 刚刚获取到的code
redirect_uri 回调地址,如果步骤一中有,那么现在也要有,而且值需要一样 ×/√
client_id 在资源服务器中注册的ID,不建议在参数中添加,应用请求头的Authorization代替 ×/√
client_secret (原文档中没提及的项,但实际应用中应该存在,所以最好使用Authorization)在资源服务器中注册的key,不建议在参数中添加,应用请求头的Authorization代替 ×/√

关于Authorization,的生成方式:先得到 client_id+":"+client_secret 字符串(例如: admin_id:admin_psw),然后在进行base64,再在前面加上"Basic",然后再放入头即可 例如 Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

步骤四 : 获取token
其实是和步骤三连连续着的,一个是请求,一个是返回
成功返回:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
  "access_token":"2YotnFZFEjr1zCsicMWpAA",  
  "token_type":"example",  //token的类型,这个有点深奥,关乎到rfc6750和其他,暂时不深入
  "expires_in":3600,            //access_token过期时间
  "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
  "example_parameter":"example_value"  //其他想添加的参数,可有可无
}

失败返回:

HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
  "error":"invalid_request"
}
参数项 说明 是否必须
error 请求类型,ASCII固定值
invalid_request:请求缺少必需的参数、包含不支持的参数值(除了许可类型)、重复参数、包含多个凭据、采用超过一种客户端身份验证机制或其他不规范的格式。
invalid_client:客户端身份验证失败(例如 Authorization 验证失败)
invalid_grant:提供的授权许可(如授权码、资源所有者凭据)或刷新令牌无效、过期、吊销、与在授权请求使用的重定向URI不匹配或颁发给另一个客户端。
unauthorized_client:进行身份验证的客户端没有被授权使用这种授权许可类型。
unsupported_grant_type:授权许可类型不被授权服务器支持。
invalid_scope:请求的范围无效、未知的、格式不正确或超出资源所有者许可的范围。
error_description 错误描述,详细的描述,没有也可以 ×
error_uri 查看错误详细的地址 ×

以上就是 授权码模式,其他模式的返回与请求,很多都是一样的,所以可能会引用上面的步骤
没错,看完 授权码模式 模式,基本就可以知道其他模式的步骤操作了,基本都差不多

模式二: 隐式授权模式


这个模式和授权模式差不多,但是中间少了code,减少了交互的次数,挺高了性能,但安全性也减低了

基本步骤
  1. 客户端 携带自己的参数(response_type,客户端标识、请求范围、state和重定向URI)跳转访问 授权端点
  2. 授权端点返回302跳转, 带着 token 跳转到 重定向端点(重定向URI)
详细步骤

** 步骤一:跳转访问 **
跟 授权码模式 的步骤一基本一样,唯一不同的地方是 response_type 的值改为 "token"

http://server.auth.com/authorize?response_type=token&client_id=asdewq&state=asd&scope=all

此时用户进行登陆后跳转

** 步骤二:授权端点返回302跳转, 带着 token 跳转到 重定向端点 **
这里的返回参数,就跟授权码模式 的步骤四中的参数一模一样,只是携带参数的方式不一样而已

授权端点的成功返回:

HTTP/1.1 302 Found
Location: http://client.auth/cb?access_token=2YotnFZFEjr1zCsicMWpAA&state=xyz&token_type=example&expires_in=3600

此时用户代理(浏览器)跳转这个页面就完成了....

模式三: 资源所有者密码凭据许可


这个协议上规定,客户端不允许记录 资源所有者账号密码的,但如果你不是服务器提供商,谁知道有没有保存?
这步

基本步骤
  1. 把 你在服务提供商(例如QQ)的账号密码提供给 客户端
  2. 客户端 用资源所有这给的账号密码(就是上步获取的账号密码)
详细步骤

步骤一:提供账号密码
这步没有要求你怎么提供,所以只要 客户端可以拿到你的账号密码就行了

步骤二:拿着账号密码去拿token

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=password&username=johndoe&password=A3ddj3w

没错,就是一个post请求就可以了
返回可以参考 授权码模式 的步骤四

模式四: 客户端凭据许可


这个是一个跟上面三个不同的模式,不需要用户的信息,那怎么知道这个用户是谁?所以这个不适合一些情况

基本步骤
  1. 没错,就一步,拿着cliend_id去拿token就可以了
详细步骤

步骤一:请求token
请求如下:就只有grant_type,和Authorization了

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials

返回一样是参考 授权码模式 的步骤四

后语

前段时间真的忙成狗了,现在刚刚辞职了,但感觉一周一更还是挺累的(虽然我现在好像也没做到→_→)...
所以 我砍掉了实现→_→....本来还是像实现的,如果真的有小伙伴想看看实现的,就留言一下吧。不过看了以上的,就基本知道怎么实现了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,757评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,478评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,540评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,593评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,903评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,329评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,659评论 2 309
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,383评论 0 195
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,055评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,337评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,864评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,227评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,820评论 3 231
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,999评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,750评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,365评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,260评论 2 258

推荐阅读更多精彩内容