既然最近在学习身份认证相关的东西,OAuth2就是一个绕不开的部分了

OAuth致力于解决的是授权相关的问题。它和认证并不相同。

OAuth致力于为跨站的授权提供解决方案,而OpenID则是为了解决跨站点认证问题,当然这两个协议有重叠处,授权和认证常常关系紧密

当前流行的OAuth版本是OAuth2.0,就是著名的OAuth2

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

OAuth允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth让用户可以授权第三方网站访问他们存储在另外服务提供者的某些特定信息,而非所有内容。

#意义 关于OAuth能给你带来什么好处,课程格子的创始人李天放在知乎有一段很棒的回答,我摘过来:

新浪微博就是你的家。偶尔你会想让一些人(第三方应用)去你的家里帮你做一些事,或取点东西。你可以复制一把钥匙(用户名和密码)给他们,但这里有三个问题:

  • 别人拿了钥匙后可以去所有的房间
  • 别人拿到你的钥匙后也许会不小心丢到,甚至故意送到它人手里。这样你都不知到谁有你家钥匙。
  • 过一段时间你也许会想要回自己的钥匙,但别人不还怎么办?

OAuth 是高级钥匙:

  • 你可以配置不同权限的钥匙。有些只能进大厅(读取你的微博流)。有些钥匙可以进储藏柜(读取你的相片)
  • 钥匙上带着指纹验证的(指纹 = appkey)。 收到钥匙的人只能自己用,不能转让
  • 你可以远程废除之前发出的钥匙相对来说, OAuth比给出用户名密码安全

相对来说, OAuth比给出用户名密码安全

我觉得以上的回答简介形象又切中要害

#原理 关于入门引导和原理介绍,阮一峰老师的博客一直是极好的学习之处,关于OAuth部分,他的博客依然精彩,我在文后给出了链接。在此引述一些关键内容

###相关名词 我们先把名词定义理清楚

  • Resource Owner(RO):资源所有者
  • Authorization Server(AS):认证服务器,即服务提供商专门用来处理认证的服务器。
  • Resource Server(RS):资源服务器,即服务提供商存放用户生成的资源的服务器。它与认证服务器,可以是同一台服务器,也可以是不同的服务器。

###基本思路 OAuth在"客户端"与"服务提供商"之间,设置了一个授权层(authorization layer)。“客户端"不能直接登录"服务提供商”,只能登录授权层,以此将用户与客户端区分开来。“客户端"登录授权层所用的令牌(token),与用户的密码不同。用户可以在登录的时候,指定授权层令牌的权限范围和有效期。

“客户端"登录授权层以后,“服务提供商"根据令牌的权限范围和有效期,向"客户端"开放用户储存的资料。

#客户端获取授权的四种模式 客户端必须得到用户的授权(authorization grant),才能获得令牌(access token)。OAuth 2.0定义了四种授权方式:

  • 授权码模式(authorization code)
  • 简化模式(implicit)
  • 密码模式(resource owner password credentials)
  • 客户端模式(client credentials)

###授权码模式 授权码模式(authorization code)是功能最完整、流程最严密的授权模式,也是我们最长见到的那种模式,当我们使用开放api的时候

步骤如下:

  1. 用户访问客户端,后者将前者导向认证服务器。
  2. 用户选择是否给予客户端授权。
  3. 假设用户给予授权,认证服务器将用户导向客户端事先指定的"重定向URI”(redirection URI),同时附上一个授权码。
  4. 客户端收到授权码,附上早先的"重定向URI”,向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。
  5. 认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。

更多细节可以阅读阮一峰老师的原文

###客户端模式 在这种模式中,用户直接向客户端注册,客户端以自己的名义要求"服务提供商"提供服务

步骤为:

  1. 客户端向认证服务器进行身份认证,并要求一个访问令牌。
  2. 认证服务器确认无误后,向客户端提供访问令牌。

之所以特意列出这种模式是因为之前为Open edX写微信后端,微信后端是一个独立的web app,采用Flask来写,由于edx信任这个应用,所以采用这种模式

#后记 ##refresh_token 之前在给Open edX写微信后端时,access_token过期的问题困扰了我很久,由于对OAuth还不够了解,我一拍脑袋重造了车轮来处理过期问题。

豆瓣的这篇文档很清楚地说明了access_token 有效期 与 refresh_token相关的问题

如果access_token过期,根据服务端返回的标识(106错误:access_token_has_expired),此时既可以再次引导用户进行授权来获取 access_token,还可以通过 refresh_token 的方式来换取新的 access_token 和 refresh_token。

refresh_token 只有在 access_token 过期时才能使用,并且只能使用一次。当换取到的 access_token 再次过期时,使用新的 refresh_token 来换取 access_token

#参考