OAuth2.0原理与实现
弄懂了原理流程,才可以搭建出来。更重要的是,可以根据原理流程自定义搭建,甚至可以完全自己实现一套,最后运行效果和原理和这个对得上就成功了,不要总期待标准答案!
首先参考两篇博客:
图分析补充:
第一步访问授权页面(然后授权服务器返回授权页面)时,即需要预先申请的开发者信息如client_id、redirect_uri,而授权服务器在第三步用户手动授权后才用到这些信息,进行页面跳转(response状态码302,附上redirect地址和授权码等),第四步是第三部redirect_uri所指向的应用开发后台地址,是第三步的网页自动重定向所访问到的,这个后台逻辑要自己写,内容是拼接redirect_uri和授权码code参数,访问认证服务器后台,申请令牌返回。这样应用获取到令牌,此后使用令牌继续访问资源服务器获取资源进行使用,由此跳转到自己的应用页面(一般是一个绑定手机号页面,使用微信账号与之绑定,是一个注册,把微信账号access_token与手机号账号绑定,存入应用自身数据库,当然access_token存在有效期,过期后也需要在用户再次登录时在自身数据库透明更新)
(A)用户访问客户端,后者将前者导向认证服务器。
(B)用户选择是否给予客户端授权。
(C)假设用户给予授权,认证服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码。
(D)客户端收到授权码,附上早先的"重定向URI",向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。
(E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。
下面是上面这些步骤所需要的参数。
A步骤中,客户端申请认证的URI,包含以下参数:
- response_type:表示授权类型,必选项,此处的值固定为"code"
- client_id:表示客户端的ID,必选项
- redirect_uri:表示重定向URI,可选项
- scope:表示申请的权限范围,可选项
- state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。
下面是一个例子。
GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: server.example.com
C步骤中,服务器回应客户端的URI,包含以下参数:
- code:表示授权码,必选项。该码的有效期应该很短,通常设为10分钟,客户端只能使用该码一次,否则会被授权服务器拒绝。该码与客户端ID和重定向URI,是一一对应关系。
- state:如果客户端的请求中包含这个参数,认证服务器的回应也必须一模一样包含这个参数。
下面是一个例子。
HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA
&state=xyz
D步骤中,客户端向认证服务器申请令牌的HTTP请求,包含以下参数:
- grant_type:表示使用的授权模式,必选项,此处的值固定为"authorization_code"。
- code:表示上一步获得的授权码,必选项。
- redirect_uri:表示重定向URI,必选项,且必须与A步骤中的该参数值保持一致。
- client_id:表示客户端ID,必选项。
下面是一个例子。
POST /token HTTP/1.1
Host: server.example.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
E步骤中,认证服务器发送的HTTP回复,包含以下参数:
- access_token:表示访问令牌,必选项。
- token_type:表示令牌类型,该值大小写不敏感,必选项,可以是bearer类型或mac类型。
- expires_in:表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。
- refresh_token:表示更新令牌,用来获取下一次的访问令牌,可选项。
- scope:表示权限范围,如果与客户端申请的范围一致,此项可省略。
下面是一个例子。
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",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter":"example_value"
}
从上面代码可以看到,相关参数使用JSON格式发送(Content-Type: application/json)。此外,HTTP头信息中明确指定不得缓存。
具体到应用开发上,无论是网站还是手机App,原理都是相同的:用户访问应用(比如微信登录功能),应用(使用申请的开发者信息如client_id、redirect_uri)访问资源服务器(微信后台,一个例子是很多App直接请求打开微信客户端,那么必然是访问微信后台),返回授权页面(微信授权)。用户输入资源服务器用户名/密码(微信),或直接获取已登录账号(比如手机App微信账号),点击授权(认证服务器验证微信账号信息)。授权后根据该应用此前传递的redirect_uri重定向到应用页面并附上授权码(code),应用使用重定向的网址和授权码访问应用自己的后台,由后台再不可见地使用redirect_uri、code到认证服务器获取令牌(access_token,可选refresh_token)返回。
一个细节是返回授权页面,传统方式是应用内嵌一个微信用户名/密码登录页面(由微信后台返回),现在一般使用二维码扫描方式。
一个例子是微信网页版的微信授权登录:
根据https://www.oschina.net/question/1172551_218058和亲自追踪,采用的是二维码ajax轮询方式:
“打开https://wx.qq.com/用FireFox看吧,它不断轮询https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid=xxxx&tip=1&_=1419316260694
用微信一扫这个结果就变了。”
“ajax轮训,前台每隔5秒访问一次后台,如果返回1这跳转,如果不是则继续查询
手机扫描二维码实际上是访问一个链接,当成功扫描,则把上一个链接返回1.这样电脑端就可以跳转了”
这个网页(打开后)上的二维码实际是不断轮询ajax访问微信后台的:
微信扫码后,微信后台一个字段改变(如此感知扫码),应用会访问到该微信用户信息(比如图片),等待授权,地址不跳转(不变),同时会继续轮询此前轮询的微信后台地址:
而扫码后的手机端,最终访问的是微信后台返回的授权页面(实际带上了应用的client_id、redirect_uri信息,经过了应用后台的转发)。手机端点击授权之后,微信后台有另一个特定标示字段的改变(数据库或缓存),这样网页二维码页面的ajax长轮询(无论的Comet技术还是WebSocket,均可立即推送这个字段值改变)就可访问到这个改变的字段,根据微信后台授权逻辑,就可立即跳转到授权后的页面(redirect_uri):
这就是网页自动跳转的原理。其实后台透明地经历了另一个获取令牌的过程,让网页直接根据令牌访问到了该微信用户(资源服务器)的有限制资源(这里特殊,几乎是该用户的所有资源)。
App应用(区别于网站应用)的授权过程表现出请求手机系统(表现为出现弹出框让用户同意)访问微信客户端,使用微信客户端(内嵌在App应用中,所以此时实际仍然在该App应用中进行操作,所以才有后来的跳转回App应用申请完授权资源后的页面)访问微信后台,返回一个授权页面(应用内访问微信,实际仍然在应用页面里)。用户点击授权后,自动跳转到应用页面(现在很多应用都有一个手机号绑定,短信验证码验证后进行绑定的页面,点击后进入真正的应用页面,一般是个人主页)。其实后台经历了一个获取授权码(authorization code)、重定向、获取令牌(access token),再用令牌有限制访问资源(仍然指微信账号信息)的过程。
令牌(access token)一般有很短的有效期(2小时),需要使用refresh_token来定期刷新,refresh_token有效期较长(30天),失效后需要用户重新授权。表现为退出登录后再微信登录,短期内不再需要用户再手动进行微信授权,说明短期内(access token有效)仍然有权访问该有限制资源(微信账号信息)。
后台需要有用户名/密码认证、授权机制,保存令牌的数据库或缓存,令牌生成接口,刷新令牌接口,过期自动删除令牌机制(参考Spring SSO的JWT令牌配置和实现),资源服务权限配置,验证令牌放行或拒绝资源访问机制。搞清这套逻辑和技术实现原理,尝试自定义实现或完全自主实现。
标准OAuth2.0系统参考:
OAuth2.0原理与实现的更多相关文章
- OAuth2.0 原理流程及其单点登录和权限控制
2018年07月26日 07:21:58 kefeng-wang 阅读数:5468更多 所属专栏: Java微服务构架 版权声明:[自由转载-非商用-非衍生-保持署名]-转载请标明作者和出处. h ...
- OAuth2.0 原理简介
写在前面: 在正式介绍OAuth2.0之前我们先来看一个场景:小李是一个文艺小青年, 经常喜欢出去旅游并且把自己旅行中的美景照片分享到各大社交网站上,比如朋友圈,新浪微博.小李马上要向女朋友求婚了,他 ...
- Oauth2.0认证原理
Oauth2.0 认证协议 Oauth2.0 应用场景: 微信联合登录 授权管理 互联网开放平台互相调用保证安全 微信提供api 给toov5调用 然后就可以获取一些微信的信息 比如微信 ...
- OAuth2.0 授权许可 之 Authorization Code
写在前面: 在前一篇博客<OAuth2.0 原理简介>中我们已经了解了OAuth2.0的原理以及它是如何工作的,那么本篇我们将来聊一聊OAuth的一种授权许可方式:授权码(Authoriz ...
- Spring security + oauth2.0 + redis + mybatis plus 搭建微服务
上个星期一个朋友请求帮忙,让我搭建一个分布式授权中心的微服务,之前我也没搭建过,在网上撸了几天前辈们写的技术博客,搞出个模型,分享给大家: 前辈们博客地址: OAuth2.0 原理:https://b ...
- OAuth2.0系列之基本概念和运作流程(一)
@ 目录 一.OAuth2.0是什么? 1.1 OAuth2.0简介 1.2 OAuth2.0官方文档 二.OAuth2.0原理 2.1 OAuth2.0流程图 三. OAuth2.0的角色 四.OA ...
- OAuth2.0认证和授权原理
什么是OAuth授权? 一.什么是OAuth协议 OAuth(开放授权)是一个开放标准. 允许第三方网站在用户授权的前提下访问在用户在服务商那里存储的各种信息. 而这种授权无需将用户提供用户名和密 ...
- [转载] OAuth2.0认证和授权原理
转载自http://www.tuicool.com/articles/qqeuE3 什么是OAuth授权? 一.什么是OAuth协议 OAuth(开放授权)是一个开放标准,允许第三方网站在用户授权的前 ...
- spring oauth2.0 实现原理
官方原文:http://projects.spring.io/spring-security-oauth/docs/oauth2.html 翻译及修改补充:Alex Liao. 转载请注明来源:htt ...
随机推荐
- rpgmakermv(8) XY_TitleMenu插件
插件作用:设置标题 /*: * @plugindesc v1.00 Display Multiple Menu in Title Screen. * @author XueYu Plugins * * ...
- hdu4746莫比乌斯反演+分块
http://blog.csdn.net/mowayao/article/details/38875021 题意: 5000组样例. 问你[1,n] 和 [1,m]中有多少对数的GCD的素因子个数小于 ...
- sitecore系统教程之内容编辑器
内容编辑器 内容编辑器是一种编辑工具,可用于管理和编辑网站上的所有内容.它专为熟悉Sitecore及其包含的功能的经验丰富的内容作者而设计. 内容编辑器的外观和功能取决于用户的角色,本地安全设置以 ...
- mysql按天,按周,按月,按季度,按年统计数据
/*查询2小时前的数据*/select * from tableName WHERE create_time HOUR) SELECT count(id) FROM rd_track_info WHE ...
- ReactiveCocoa(III)
flatMap(FlattenStrategy.latest) observe(on: UIScheduler()).startWithResult 切换线程: observeOn(UISchedul ...
- Collections集合工具类的方法
addAll & shuffle: 返回类型为boolean类型,执行完操作不接收也行: 其中,静态方法,与对象无关,类名点方法名直接调用: 点点点为可变参数,随便填写几个参数都可以: sor ...
- 转:【专题十二】实现一个简单的FTP服务器
引言: 休息一个国庆节后好久没有更新文章了,主要是刚开始休息完心态还没有调整过来的, 现在差不多进入状态了, 所以继续和大家分享下网络编程的知识,在本专题中将和大家分享如何自己实现一个简单的FTP服务 ...
- Windows Services(NT)
本文主要记录什么是Windows Service,及其主要组成?并通过一个列子来创建一个Windows Services,同时,记录几个在查资料碰到的问题. Windows Services全文简称N ...
- SQL SERVER镜像配置(包含见证服务器)
镜像简介 重要说明:保持数据库镜像运行.如果您关闭数据库镜像,则必须执行完全备份并还原数据库以重建数据库镜像. 一. 简介 SQL SERVER 2005镜像基于日志同步,可良好实现故障转移. ...
- mysql union 和 left join 结合查询用法
union 和 left join 结合查询用法 SELECT u.nickname,z.group_comming_type,z.id,z.user_id,z.title,z.create_time ...