简介

在现代的网站中,我们经常会遇到使用OAuth授权的情况,比如有一个比较小众的网站,需要用户登录,但是直接让用户注册就显得非常麻烦,用户可能因为这个原因而流失,那么该网站可以使用OAuth授权,借助于github或者其他的第三方网站的认证授权,来获取相关的用户信息,从而避免了用户注册的步骤。

当然,很可能在第三方网站上授权获得用户信息之后,还需要在本网站填写一些必要的信息进行绑定,比如手机号,用户名等等。

但是这比单纯的注册要方便太多了,也容易让用户接受。

今天,我们将要讲解一下OAuth 2.0授权框架的构成,希望大家能够喜欢。

OAuth的构成

在传统的CS模式的授权系统中,如果我们想要借助第三方系统来访问受限的资源,第三方系统需要获取到受限资源服务器的用户名和密码,才能进行对资源服务器的访问,很显然这个是非常不安全的。

在OAuth2中,我们是怎么做的呢?

我们先来看一下OAuth2中授权的流程图:

一般来说OAuth2中有4个角色。

resource owner: 代表的是资源的所有者,可以通过提供用户名密码或者其他方式来进行授权。通常来是一个人。

resource server:代表的是最终需要访问到资源的服务器。比如github授权之后获取到的用户信息。

client: 用来替代resource owner来进行交互的客户端。

authorization server: 用来进行授权的服务器,可以生成相应的Access Token。

整个流程是这样的:

Client向resource owner发起一个授权请求,resource owner输入相应的认证信息,将authorization grant返回给client。

client再将获取到的authorization grant请求授权服务器,并返回access token。

client然后就可以拿着这个access token去请求resource server,最后获取到受限资源。

refresh Token

为了安全起见,access token总是有过期时间的,那么如果token过期了怎么办呢?

具体的办法就是refresh Token :

我们看一下refresh token的流程图:

前面的A,B,C,D和之前的讲到的流程是一致的。

如果接下来访问资源的时候,access token过期了,那么client会再次向认证服务发出refresh token的请求。

然后认证服务器会再次返回新的access token.

Authorization Code模式

上面我们讲到的模式中,Client会保存Authorization Grant信息,并通过这个信息来去授权服务器请求Access Token。

Client直接保存Authorization Grant信息,并和授权服务器进行通信,这对client会有一定的安全限制。

如果是在web环境中,client是借助user-agent(web浏览器)来进行访问的该如何处理呢?

这里向大家介绍一个Authorization Code模式。

Client通过User-Agent发起请求,并附带跳转链接。当提供了用户的授权认证信息之后,授权服务器返回的不是token而是authorization code,拿到这个code之后,client可以通过这个code来获取access Token或者refresh Token。

上面的授权流程图我们可以通过一个具体的例子来说明,resource owner就是我们要访问的资源。 Authorization Server是第三方的授权服务器,比如github的授权服务。而User-Agent就是浏览器。

好了,我们开始具体流程的讲解:

比如用户想获取www.flydean.com的信息,但是需要登录,这个时候就跳转到github的登录界面,我们输入github的用户名密码,github会返回一个Authorization Code到我们的服务器比如 www.flydean.com/?code=code, client拿到这个code之后,会去后台请求github,去验证这个code的合法性,如果code合法,则github会返回access token的信息,client后面就可以通过access token去github资源服务器资源了。

举一个具体的access 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",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter":"example_value"
}

隐式授权

在上面我们讲到的几个模式中,client都需要直接和授权服务器进行通信,从而获取到access Token,有没有什么方式可以不需要client和授权服务器直接通信就可以得到access token呢?

接下来我们讲一下隐式授权。

上图就是一个隐式授权的例子,和Authorization Code模式不同的是,授权服务器返回的是一个access token片段,只有这个片段,我们是无法得到access token的。

这里我们需要额外请求一次client resource服务器,服务器将会返回一个script脚本,通过这个脚本,我们对access token片段进行解析,得到最终的access token。

Resource Owner 授权密码认证

这种模式一般出现在resource owner非常信任client的情况下。

我们先看一下流程图:

这种模式实际上相当于用户将密码交给client保管,由client使用保存好的用户名密码向授权服务器请求资源。

Client 认证授权

这种模式下,client本身是有一定的授权范围的,可以通过client认证授权,直接获取到授权服务器的access token。

github的OAuth2认证流程

上面讲的通用流程中,其实很多角色都可以合并的。

接下来我们具体讲解一下如何使用github的OAuth2进行授权。

要使用github的OAuth2,需要首先在github中进行OAuth服务的注册。

点击注册按钮,输入相应的信息,我们就可以完成注册了。

这里比较重要的就是callback url,我们会通过这个callback url来传递授权信息。

注册成功之后,你会得到一个Client ID和Client Secret。

github的授权步骤分为三个部分:

用户跳转到github的认证页面进行授权

在这一部分中,我们需要跳转到github的授权页面:

https://github.com/login/oauth/authorize

上面是跳转页面的链接,这个链接可以接下面几个参数:

client_id: 必须的参数,是我们上面注册app得到的client id。

redirect_uri: 可选参数,如果不设定,则会使用注册的时候提供的callback uri。

login:可选参数,指定具体的认证用户名。

scope:github中权限的范围。

state: 是一个随机数,用来防止cross-site攻击。

allow_signup: 是否允许在认证的时候注册。

看一下跳转的页面:

用户跳转回要访问的资源页面

当用户授权之后,就会调整到callback页面,并带上code:

http://www.flydean.com/login?code=b14a2dd57f11b2310f42

应用程序拿到code之后,通过调用下面的请求来获取access token:

POST https://github.com/login/oauth/access_token

这个post请求需要带上client_id,client_secret,code这三个必须的参数,还可以带上两个可选的参数redirect_uri和state。

默认情况下,我们会获取到下面的响应信息:

access_token=e72e16c7e42f292c6912e7710c838347ae178b4a&token_type=bearer

应用程序拿到access token获取到github用户信息

有了access token之后,我们需要将token放到请求head中,去请求用户信息:

Authorization: token OAUTH-TOKEN
GET https://api.github.com/user

总结

OAuth2是一个非常常用的协议,也非常的方便,主要目的就是可以使第三方服务器可以获得授权范围内的用户信息。希望大家能够喜欢。

本文作者:flydean程序那些事

本文链接:http://www.flydean.com/oauth-2-0-in-depth/

本文来源:flydean的博客

欢迎关注我的公众号:「程序那些事」最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

OAuth 2.0授权框架详解的更多相关文章

  1. 转 OAuth 2.0授权协议详解

    http://www.jb51.net/article/54948.htm 作者:阮一峰 字体:[增加 减小] 类型:转载 时间:2014-09-10我要评论 这篇文章主要介绍了OAuth 2.0授权 ...

  2. OAuth 2.0 授权认证详解

    一.认识 OAuth 2.0 1.1 OAuth 2.0 应用场景 OAuth 2.0 标准目前被广泛应用在第三方登录场景中,以下是虚拟出来的角色,阐述 OAuth2 能帮我们干什么,引用阮一峰这篇理 ...

  3. OAuth 2.0 开发完全详解

    --------------------------基础篇------------------------------- I:OAuth 2.0 概述 首先大家来看看国内新浪跟腾讯这两大头对OAuth ...

  4. Android 7.0 IMS框架详解

    本文主要讲解IP Multimedia Subsystem (IMS)在Android 7.0上由谷歌Android实现的部分内容.从APP侧一直到Telephony Framework,是不区分CS ...

  5. OAuth 2.0 RFC 框架 中文

    Internet Engineering Task Force (IETF) D. Hardt, Ed.Request for Comments: 6749 MicrosoftObsoletes: 5 ...

  6. Spark2.1.0——内置Web框架详解

    Spark2.1.0——内置Web框架详解 任何系统都需要提供监控功能,否则在运行期间发生一些异常时,我们将会束手无策.也许有人说,可以增加日志来解决这个问题.日志只能解决你的程序逻辑在运行期的监控, ...

  7. Spark2.1.0——内置RPC框架详解

    Spark2.1.0——内置RPC框架详解 在Spark中很多地方都涉及网络通信,比如Spark各个组件间的消息互通.用户文件与Jar包的上传.节点间的Shuffle过程.Block数据的复制与备份等 ...

  8. iOS 开发之照片框架详解

    转载自:http://kayosite.com/ios-development-and-detail-of-photo-framework.html 一. 概要 在 iOS 设备中,照片和视频是相当重 ...

  9. Shiro 安全框架详解二(概念+权限案例实现)

    Shiro 安全框架详解二 总结内容 一.登录认证 二.Shiro 授权 1. 概念 2. 授权流程图 三.基于 ini 的授权认证案例实现 1. 实现原理图 2. 实现代码 2.1 添加 maven ...

随机推荐

  1. Python之for循环和列表

    for循环: 有限循环 基本语法: for 变量 in 可迭代对象: 循环体 也可使用break,continue,for else list列表初识: 列表可放任意数据类型:[int,str,boo ...

  2. JavaScript实现异步的4中方法

    一:背景简介 Javascript语言的执行环境是"单线程"(single thread). 所谓"单线程",就是指一次只能完成一件任务.如果有多个任务,就必须 ...

  3. C# 将dataset数据导出到excel中

    //添加引用 NPOI.dll //添加 using NPOI.HSSF.UserModel; /// <summary> /// 导出数据到Excel /// </summary& ...

  4. Linux用户和组管理命令-用户删除userdel

    删除用户 userdel 可删除Linux 用户 格式: userdel [OPTION]... Login 常见选项: -f, --force 强制 -r, --remove 删除用户家目录和邮箱 ...

  5. 边界层吞吸技术(BLI)

    气流在机体表面前进时,由于受到摩擦,其速度会不断降低,从而会产生湍流甚至气流分离,而流动分离又会造成大量紊流.涡,使升力大量损失,同时也会造成阻力急剧增加.边界层吞吸技术就是一种对附面层气流" ...

  6. BrowserSync 热更新的使用(保存后自动刷新)

    BrowserSync使用的优点,BrowserSync监听条件中的文件,发现更新会立刻刷新浏览器,就像 vue中的热更新一样,解放F5实现自动更新,提高开发效率, 解决了使用双屏幕时来回切换的烦恼! ...

  7. 10 Servlet_02 资源跳转(主要是内部转发)与中文乱码问题

    总的知识点: 1.小的知识点总结: alt + shift + r 重命名快捷键(可以给包和类以及项目重命名) 有序列表 ol li 无序列表 ul type 格式 text 是文本类型 passwo ...

  8. 看完这篇 final、finally 和 finalize 和面试官扯皮就没问题了

    我把自己以往的文章汇总成为了 Github ,欢迎各位大佬 star https://github.com/crisxuan/bestJavaer 已提交此篇文章 final 是 Java 中的关键字 ...

  9. Linux 系统编程 学习 总结

    背景 整理了Liunx 关于 进程间通信的 很常见的知识. 目录 与 说明 Linux 系统编程 学习:000-有关概念 介绍了有关的基础概念,为以后的学习打下基础. Linux 系统编程 学习:00 ...

  10. Go语言反射(reflect)及应用

    Go语言反射(reflect)及应用 基本原理及应用场景 在编译时不知道类型的情况下,可更新变量.在运行时查看值.调用方法以及直接对它们的布局进行操作,这种机制被称为反射. 具体的应用场景大概如下: ...