何宏伟

Read and Think

[嵌牛导读]

OAuth

OAuth是一个关于授权(authorization)的网络开放标准,在全世界被广泛应用,像Google,Github,Sina微博等都采取OAuth,目前是2.0版本。本文是对我自己开发中的理解做一个总结,同时也是想用自己的方式尝试阐述OAuth的设计机制和原理。

[嵌牛鼻子]

OAuth,Access Token,Third-party application,Authorization Server,Resource Server

[嵌牛提问]

  • 当你向需要获取资源的目标发送资源使用请求时,采用什么方式?
  • 目标资源是如何确立你的身份?
  • 对于目标资源的使用范围如何控制,如何保证资源的合理使用?

[嵌牛正文]

在我使用Github的API提交issue,或是获取个人仓库信息,个人资料是我第一次遇到OAuth认证流程,尽管有官方的文档,可还是步履艰难,到最后获取到个人资料认证成功花费了很长时间。可是,从现在来看,整个OAuth认证流程非常简单 - 四个字“你来我往”

一. 应用场景

Github

在搭建博客时候,综合查找的各方资料最终选择Gitment作为评论组件集成到自己的博客。Gitment的评论组件正是使用的Github的API和仓库的issues来做为基础建立的,那么Gitment是如何获取到评论的Github用户的?

采用传统方法,Gitment需要拿到Github用户的用户邮箱和密码,来通过Gitment提交用户邮箱和密码实现API操作。这样的做法漏洞很多:

  • 为了能够在后续操作中继续使用API,需要保存用户邮箱和密码,这相当于将自己的账号曝光
  • Gitment在获取用户邮箱和密码后,使用API操作个人资料时权限及操作范围无法界定,非常危险
  • 要想从Gitment中解脱出来,必须修改密码,一旦修改密码会导致在这之前的第三方应用密码失效
  • 一旦有一个第三方应用不严谨,密码被破解,那么个人账户无疑处在非常危险的境地

OAuth正是为此诞生。

二. OAuth的认证思路

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

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

三. OAuth认证原理

Coding OAuth
(A)用户打开第三方应用客户端以后,客户端要求用户给予授权。
(B)用户同意给予第三方应用客户端授权。
(C)客户端使用上一步获得的授权,向认证服务器申请令牌。
(D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌(令牌作为身份认证的密令)。
(E)客户端使用令牌,向资源服务器申请获取资源。
(F)资源服务器确认令牌无误,同意向客户端开放资源。

我的总结就是四个字 - “你来我往”

你使用第三方应用,第三方应用需要你授权,你授权,第三方应用通过你的授权来申请令牌,认证服务器确认令牌无误发放令牌给第三方应用,第三方应用携带令牌访问所需资源,资源服务器确认令牌开放资源给第三方应用。

四. 授权方式

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

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

本文着重介绍授权码模式(功能完整,流程严格),使用比较广泛。

图片来自阮一峰博客

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

A步骤中HTTP请求需要携带固定的参数,包括:

  • response_type: 表示授权类型,默认“code”
  • cliend_Id: 第三方应用的客户端ID,必选
  • redirect_uri: 重定向的URI,必选
  • scope: 申请的权限范围,可选项(有默认值)

严格遵循授权码模式的操作步骤,提供正确的请求参数,你的token马上到


END

参考
阮一峰网络日志 | Coding OAuth

收藏
评论加载中...