一、OAuth 概念

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

严格来说,OAuth2 不是一个标准协议,而是一个安全的授权框架。其详细描述系统中不同角色,用户,服务前端应用(如 API )以及客户端(如网站或APP)之间如何实现相互认证

当前 OAuth 协议版本是 OAuth2.0,需要注意的是,OAuth2.0 并不向下兼容 OAuth1.0。

在生活中,比较常见的 OAuth2 的使用场景是授权登录,并且也广泛应用于 web、桌面应用和移动 APP 的第三方服务提供授权登录验证机制,以实现不同应用直接数据访问的权限

二、OAuth2 重点名词介绍

在 OAuth2 标准中定义了以下四种角色:

  • 资源拥有者 (Resource Owner):

代表授权客户端访问本身资源信息的用户(User);

  • 客户端 (Client):

代表意图访问受限资源的第三方应用。

  • 资源服务器 (Resource Server):

代表托管了受保护的用户账号信息的服务器,它与认证服务器,可以是同一台服务器,也可以是不同的服务器;

  • 授权服务器 (Authorization Server):

代表验证用户身份然后为客户端派发资源访问令牌的服务器,即服务提供商专门用来处理认证的服务器;

三、OAuth2 运行流程

1. 流程分析

(配图来自阮一峰大佬

大致流程概括就是:

  • (A)Authrization Request

用户打开客户端以后,客户端要求用户给予授权。

  • (B)Authorization Grant(Get)

用户同意给予客户端授权。

  • (C)Authorization Grant(Post)

客户端向授权服务器发送它自己的客户端身份标识和上一步中获得的授权(authorization grant),向认证服务器申请令牌。

  • (D)Access Token(Get)

认证服务器对客户端进行认证以后,确认无误,同意发放令牌(access token),授权阶段至此全部结束。

  • (E)Access Token(Post && Validate)

客户端使用令牌,向资源服务器申请获取资源。

  • (F)Protected Resource(Get)

资源服务器确认令牌无误,同意向客户端开放资源。

理解完上面整个流程以后,我们再看看下面这张图,能更加清晰理解 OAuth2 的整个运行流程:

(配图来自公众号前端修仙之路

从整个流程可以看出,在 B 步骤最为关键,即需要获取到用户对客户端的授权(如我们在微信扫码登录时,点击“确定”按钮的步骤)。

有了这个授权以后,客户端才能拿到令牌,进而凭令牌向资源服务器获取资源。

2. 案例:微信登录

另外,微信登录的实现流程也类似:

(配图来自微信官方文档

其整体流程为:

  1. 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据 code 参数;

  2. 通过 code 参数加上 AppID 和 AppSecret 等,通过 API 换取 access_token ;

  3. 通过 access_token 进行接口调用,获取用户基本数据资源或帮助用户实现基本操作

3. OAuth2 优缺点

  • 优点:

适合快速开发实施,代码量少,API需要被不同APP使用,且每个APP使用方式也不同的情况。

  • 缺点:

学习和理解的成本比较大,并且 OAuth2 不是一个严格的标准协议,在实施过程中更容易出错。

四、OAuth2 四种授权模式

通过前面描述,可以知道OAuth 的核心就是向第三方应用颁发令牌。

OAuth 2.0 规定了四种获得令牌的流程。你可以选择最适合自己的那一种,向第三方应用颁发令牌。即以下四种授权方式:

  • 授权码(authorization-code)

  • 隐藏式(implicit)

  • 密码式(password)

  • 客户端凭证(client credentials)

注意:

不管哪一种授权方式,第三方应用申请令牌之前,都必须先到系统备案,说明自己的身份,然后会拿到两个身份识别码:客户端 ID(client ID)客户端密钥(client secret)

这是为了防止令牌被滥用,没有备案过的第三方应用,是不会拿到令牌的。

1. 授权码(authorization code)

第三方应用先申请一个授权码,然后再用该码获取令牌

适用于有后端的 Web 应用,授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。

这种方式也是最常用的流程,安全性最高

整体流程

(配图来自阮一峰大佬

步骤分析

  1. 用户从 A 网站跳转到 B 网站,请求用户确认授权,以获取授权码,其发送链接示意如下:

https://b.com/oauth/authorize?
response_type=code&
client_id=CLIENT_ID&
redirect_uri=CALLBACK_URL&
scope=read

其中:

response_type 参数表示要求返回授权码(code);

client_id 参数让 B 知道是谁在请求;

redirect_uri 参数是 B 接受或拒绝请求后的跳转网址;

scope 参数表示要求的授权范围(这里是只读);

  1. 在 B 网站中,当用户同意授权 A 网站,则 B 网站会携带授权码,重定向到 redirect_uri 参数指定的网址,就像下面这样:

https://a.com/callback?code=AUTHORIZATION_CODE
  1. A 网站获取授权码以后,在 A 网站后端中向 B 网站请求令牌:

https://b.com/oauth/token?
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET&
grant_type=authorization_code&
code=AUTHORIZATION_CODE&
redirect_uri=CALLBACK_URL

client_id 参数和 client_secret 参数用来让 B 确认 A 的身份( client_secret 参数是保密的,因此只能在后端发请求);

grant_type 参数的值是 AUTHORIZATION_CODE ,表示采用的授权方式是授权码;

code 参数是上一步拿到的授权码;

redirect_uri 参数是令牌颁发后的回调网址;

  1. B 网站接受请求并验证身份,身份验证通过后,会发放令牌。向 redirect_uri 指定的网址,发送包含令牌 access_token 字段的JSON数据,流程完毕。

2. 隐藏式(implicit)

隐藏授权码步骤,直接向前端发放令牌,也称授权码隐藏式。

整体流程

(配图来自阮一峰大佬

步骤分析

  1. 用户从 A 网站跳转到 B 网站,要求授权用户数据给 A 网站使用。

https://b.com/oauth/authorize?
response_type=token&
client_id=CLIENT_ID&
redirect_uri=CALLBACK_URL&
scope=read

response_type 参数为 token,表示要求直接返回令牌

  1. 用户在 B 网站同意授权给 A 网站。

当用户同意授权后,会跳转到 redirect_uri 参数指定的重定向地址,并将令牌作为 URL 参数传递给 A 网站。

https://a.com/callback#token=ACCESS_TOKEN

token 参数就是令牌,A 网站因此直接在前端拿到令牌。

注意:

这里的令牌位置是 URL 锚点(即 # 号),而不是查询字符串,这是因为锚点不会发到服务器,避免泄露令牌的风险。

适用场景:

由于直接传递令牌不安全,因此常常适用在对安全要求不高的场景,并且令牌有效期非常短,例如会话期间(session)有效,关闭浏览器便失效。

3. 密码式(password)

即:对于信任的应用,可以携带约定的用户名和密码进行令牌申请

流程分析

  1. A 网站使用 B 网站提供的用户名和密码,向 B 网站发起令牌请求。

https://oauth.b.com/token?
grant_type=password&
username=USERNAME&
password=PASSWORD&
client_id=CLIENT_ID

grant_type 参数是授权方式,这里的 password 表示"密码式"; username 和 password 是 B 的用户名和密码。

  1. B 网站验证身份后直接将令牌存在 JSON 数据中,作为 HTTP 相应返回令牌给 A 网站。

适用场景:

风险较大,一般适用在对应用高度信任的情况。

4. 客户端凭证(client credentials)

即:给出凭证让对方确认并提供令牌

流程分析

  1. A 应用在命令行向 B 发出请求。

https://oauth.b.com/token?
grant_type=client_credentials&
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET

grant_type 参数等于 client_credentials 表示采用凭证式; client_id 和 client_secret 用来让 B 确认 A 的身份。

  1. B 网站验证身份后返回令牌。

这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。

适用场景:

通过命令行请求令牌。

流程分析

五、使用令牌

当网站获取到令牌以后,接下来每个 API 请求都需要带上令牌,其做法是在请求的头信息中,将令牌添加 Authorization 字段中。

六、更新令牌

当令牌有效期到了,OAuth2 允许用户自动更新令牌,而不用让用户重新授权获取新令牌。

具体流程:

在 B 网站发放令牌时,一次性发放 2 个令牌,一个用于获取数据,一个用于获取新的令牌( refresh token 字段)。令牌到期后,用户使用 refresh token 发送请求去更新令牌:

https://b.com/oauth/token?
grant_type=refresh_token&
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET&
refresh_token=REFRESH_TOKEN

grant_type 参数为 refresh_token 表示要求更新令牌; client_id 参数和 client_secret 参数用于确认身份; refresh_token 参数就是用于更新令牌的令牌。

B 网站验证通过以后,就会颁发新的令牌。

参考文章

  1. 部门内部培训资料

  2. 《OAuth 2 深入介绍》https://dwz.cn/kQo0iNeY

  3. 《阮一峰 理解OAuth 2.0》https://dwz.cn/9XhoQ8DB

  4. 《阮一峰 OAuth 2.0 的四种方式》https://dwz.cn/sbSt4DlZ

回复“加群”与大佬们一起交流学习~

【全栈修炼】396- OAuth2 修炼宝典的更多相关文章

  1. 【全栈修炼】OAuth2 修炼宝典

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

  2. 洗礼灵魂,修炼python(73)--全栈项目实战篇(1)——【转载】前提准备之学习ubuntu

    本篇是为项目实战做准备,学习Linux是必备的,不然都不好意思叫全栈对吧?下面是一位资深大神写的文章,够详细,我也不用浪费时间再写了 原文链接:Ubuntu学习——第一篇 内容: 一. Ubuntu简 ...

  3. 怎样成为全栈工程师(Full Stack Developer)?

    "Facebook 工程师说 Facebook 只招 full stack engineer,那么 Facebook engineer 都是怎样的人啦."? 具体经验不重要,重要的 ...

  4. 2019 Java 全栈工程师进阶路线图,一定要收藏

    技术更新日新月异,对于初入职场的同学来说,经常会困惑该往那个方向发展,这一点松哥是深有体会的. 我刚开始学习 Java 那会,最大的问题就是不知道该学什么,以及学习的顺序,我相信这也是很多初学者经常面 ...

  5. 2019年java全栈工程师学习大全

    技术更新日新月异,对于初入职场的同学来说,经常会困惑该往那个方向发展,这一点我是深有体会的. 我刚开始学习 Java 那会,最大的问题就是不知道该学什么,以及学习的顺序,我相信这也是很多初学者经常面临 ...

  6. JAVA全栈工程师学习线路(建议收藏)

    互联网技术,更新迭代迅速,用日新月异来说也不为过,所以,面对这这种大环境,对于码农尤其是那些对于初入职场的新手来说,该如何自我学习升级,往方向发展,这一点是大家都经常困惑的. 大部分人,刚开始学习的J ...

  7. vuejs、eggjs全栈式开发设备管理系统

    vuejs.eggjs全栈式开发简单设备管理系统 业余时间用eggjs.vuejs开发了一个设备管理系统,通过mqtt协议上传设备数据至web端实时展现,包含设备参数分析.发送设备报警等模块.收获还是 ...

  8. vuejs、eggjs、mqtt全栈式开发设备管理系统

    vuejs.eggjs.mqtt全栈式开发简单设备管理系统 业余时间用eggjs.vuejs开发了一个设备管理系统,通过mqtt协议上传设备数据至web端实时展现,包含设备参数分析.发送设备报警等模块 ...

  9. 【Spring Cloud & Alibaba全栈开源项目实战】:SpringBoot整合ELK实现分布式登录日志收集和统计

    一. 前言 其实早前就想计划出这篇文章,但是最近主要精力在完善微服务.系统权限设计.微信小程序和管理前端的功能,不过好在有群里小伙伴的一起帮忙反馈问题,基础版的功能已经差不多,也在此谢过,希望今后大家 ...

  10. 通往全栈工程师的捷径 —— react

    腾讯Bugly特约作者: 左明 首先,我们来看看 React 在世界范围的热度趋势,下图是关键词“房价”和 “React” 在 Google Trends 上的搜索量对比,蓝色的是 React,红色的 ...

随机推荐

  1. [深度学习][图像处理][毕设][笔记][安装环境][下载地址]安装VS2013、matconvnet、cuda、cudnn过程中产生的一些记录,2018.5.6号

    最近半个多月,被cuda等软件折磨的死去活来,昨天下午,终于安装好了环境,趁着matlab正在,在线下载VOT2016数据集,3点睡眼惺忪被闹醒后,睡不着,爬上来写这份记录. 先记录一下自己电脑的基本 ...

  2. Intellij IDEA搭建JSP+Tomcat开发环境

    1.新建项目 然后填入项目名称和选择项目路径,填完点击完成. 2.添加WEB框架 别问我为什么不一开始就直接新建WEB框架,因为我也是看的别人的教程0.0 不过还遇到了一些新问题,后面会讲到 3.配置 ...

  3. Graphviz 画图的一些总结

    Graphviz Graphviz 是一个自动排版的作图软件,可以生成 png pdf 等格式. 一切以官方文档为准,博客只是参考.这里做一个自己学习的记录. dot 语法介绍 部分图形属性介绍 示例 ...

  4. hdu 1880 魔咒词典(双hash)

    魔咒词典Time Limit: 8000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  5. requests模拟登陆的三种方式

    ###获取登录后的页面三种方式: 一.实例化seesion,使用seesion发送post请求,在使用他获取登陆后的页面 import requests session = requests.sess ...

  6. 力扣(LeetCode)删除排序链表中的重复元素II 个人题解

    给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字. 思路和上一题类似(参考 力扣(LeetCode)删除排序链表中的重复元素 个人题解)) 只不过这里需要用到一个前 ...

  7. PL真有意思(一):引言

    前言 断断续续学编译原理到之前发过写一个编译器和正则表达式引擎系列文章也有一段时间了,然后最近看完PLP这本书,这本书应该算是入门书,但是对我这种半吊子收获很大.所以为了弥补最近学操作系统和接外包摸的 ...

  8. 看淡生死,不服就干(C语言指针)

    看淡生死,不服就干 emmmmm 其实今天蛮烦的 高等数学考的一塌糊涂 会的不会的都没写 真心没有高中轻松了啊 也不知道自己立的flag还能不能实现 既然选择了就一定坚持下去啊 下面还是放一段之前写的 ...

  9. GitHub注册失败,卡在第一步

    同事说他无法注册GitHub,我一开始以为GitHub又无法登录进去,我就登录了自己的GitHub账号,没有问题,可以登录啊,见第一个标签页.同一局域网,不可能我能登录,你无法完成注册啊.于是,我就在 ...

  10. Mybaits学习总结

    一.Mybatis介绍 邮箱:1727292697 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的 ...