##1、写在前面
在收集资料时,我查询和学习了许多介绍OAuth的文章,这些文章有好有坏,但大可能是从个例出发。所以我想从官方文档出发,结合在stackoverflow上的一些讨论,一并整理一下。整理的内容分为OAuth1.0a和OAuth2两部分。html
OAuth 1.0a:One Leg ->Two Leg -> Three Legged
OAuth 2:Two Leg ->Three Legged (附:Refresh Token的方式)浏览器
这两种模式都是按箭头从左往右安全性递增,其实现也会相对复杂。关于官方的这种leg(腿?)的说法,在中文翻译中比较少有文章说起。下面分别来介绍OAuth的这5种受权流程。安全
##2、OAuth1.0a
2.1 OAuth 1.0a (One Leg)服务器
- 应用给服务器发送一个签名请求,附带如下参数:
- oauth_token Empty String
- oauth_consumer_key
- oauth_timestamp
- oauth_nonce
- oauth_signature
- oauth_signature_method
- oauth_version Optional
- 服务验证并授予对资源的访问
- 应用程序利用请求的资源
2.2 OAuth 1.0a (Two Legs)cookie
- 应用发送一个签名请求,以获取 Request Token:
- oauth_consumer_key
- oauth_timestamp
- oauth_nonce
- oauth_signature
- oauth_signature_method
- oauth_version Optional
- 服务器返回Request Token:
- oauth_token
- oauth_token_secret
- Additional Parameters / Arguments
- 发送签名请求,用Request Token换取Access Token
- oauth_token Request Token
- oauth_consumer_key
- oauth_nonce
- oauth_signature
- oauth_signature_method
- oauth_version
- 服务器返回Access Token和Token Secret
- 应用经过Access Token和Token Secret利用请求的资源
2.3 OAuth 1.0a (Three Legged)session
- 应用发送一个签名请求,以获取 Request Token:
- oauth_consumer_key
- oauth_timestamp
- oauth_nonce
- oauth_signature
- oauth_signature_method
- oauth_version Optional
- 服务器返回Request Token:
- oauth_token
- oauth_token_secret
- oauth_callback_confirmed
- … Additional Parameters / Arguments
- 发送给用户受权的URL
- 提示用户进行受权
- 用户进行受权
- 受权结束后返回应用,附带上:
- oauth_token
- oauth_verifier
- 发送签名请求,用Request Token换取Access Token
- oauth_token Request Token
- oauth_consumer_key
- oauth_nonce
- oauth_signature
- oauth_signature_method
- oauth_version
- oauth_verifier
- 服务器返回Access Token和Token Secret
- 应用经过Access Token和Token Secret利用请求的资源
##3、OAuth2app
3.1 OAuth 2 (Two Legged)dom
3.1.1 客户端凭据方式ide
- 应用发送请求到服务器:
- grant_type = client_credentials
若是没有使用Authorization(Authorization: Basic Base64(client_id:client_secret)) 的header,必须附带参数为:
- client_id
- client_secret
- 服务器以Access Token回应
- access_token
- expires_in
- token_type
3.1.2 隐式授予方式学习
- 应用发送请求到服务器:
- response_type = token
- redirect_uri This is a server-side Redirection URI hosted by the provider or yourself.
- scope
- state Optional
- client_id
- 用户可根据须要受权。
- 服务器将响应包含access_token在内的redirect_uri
- 应用程序跳转至redirect_uri
- redirect_uri将响应一段脚本或HTML片断。响应的脚本或HTML片断包含参数access_token,还有您可能须要的任何其余参数。
3.1.3 资源全部者密码方式
- 应用向资源全部者请求凭证
- 应用使用凭证,向服务器发送请求
- grant_type = password
- username
- password
url看起来会像这样:grant_type=password&username=my_username&password=my_password
若是你没有使用Authorization的header,必须附带上参数:
- client_id
- client_secret
url看起来会像是:
grant_type=password&username=my_username&password=my_password&client_id=random_string&client_secret=random_secret
- 服务器返回Access Toke
- access_token
- expires_in
- token_type
3.2 OAuth 2 (Three Legged)
- 应用重定向用户到受权服务:
- client_id
- redirect_uri
- response_type
- state Optional; Unique identifier to protect against CSRF
- scope Optional; what data your application can access.
url看起来会像是:
oauth_service/login/oauth/authorize?client_id=3MVG9lKcPoNINVB&redirect_uri=http://localhost/oauth/code_callback&scope=user
- 用户登陆服务器并确认受权给应用
- 服务器重定向用户到redirect_url ,附带参数:
- 应用拿到code,并换取Access Token
- client_id
- client_secret
- code
- redirect_uri Optional;
- grant_type = “authorization_code”
- 若是的client_id和client_secret是有效的,服务器将调用一个回调redirect_url,包含ACCESS_TOKEN
- access_token
- expires_in
- refresh_token
- 应用保存ACCESS_TOKEN,在随后的请求中使用。一般这个值被存储在session或或cookie,须要时做为受权请求的参数。
3.3 OAuth 2 (Refresh Token 刷新token)
在OAuth2中,Token会有过时时间,咱们必须去refresh_token,使用其余一些先前得到的参数,生成一个新的token。这是一个容易得多的流程。
- 建立刷新令牌请求
- grant_type = “refresh_token”
- scope Optional; Cannot have any new scopes not previously defined.
- refresh_token
- client_id
- client_secret
- 服务验证和响应如下参数:
##4、stackoverflow上的一些问答
Q:OpenID和OAuth的区别是什么?
A:OpenID是有关身份验证(即证实你是谁),OAuth有关受权(即授予访问权限),推荐博文:从用户的角度来看OpenID和OAuth
Q:OAuth2与OAuth1不一样的地方是?有人能够简单的解释的OAuth2和OAuth1之间的区别吗? OAuth1如今已通过时,应实施的OAuth2?我没有看到许多实现的OAuth2,大多数仍在使用OAuth,这让我怀疑的OAuth2的准备使用。是吗?
A:OAuth2能更好地支持不是基于浏览器的应用。对于不是基于浏览器的应用程序,这是对OAuth的主要挑战。例如,在OAuth1.0,桌面应用或手机应用必须引导用户打开浏览器所需的服务,与服务进行身份验证,并复制令牌从服务返回给应用程序。这里的主要批评是针对用户体验。使用OAuth2.0,能够用新的方式为用户的应用程序得到受权。
OAuth2.0再也不须要客户端应用程序拥有密钥。这让人回想起老的Twitter认证的API,它并不须要应用获得HMAC哈希令牌和请求字符串。使用OAuth2.0,应用程序能够经过HTTPS得到令牌。
OAuth2.0的签名流程简单得多。没有更多的特殊解析,排序,或编码。
OAuth2.0的访问令牌是“短命”的。一般状况下,OAuth1.0的访问令牌能够存储一年或一年以上(Twitter历来没有让他们到期)。 OAuth的2.0有刷新令牌的概念。虽然我不能彻底确定这是什么意思,个人猜想是,您的访问令牌能够是短暂存储的(即基于会话),而你能够刷新令牌。你使用刷新令牌获取新的访问令牌,而不是让用户从新受权您的应用程序。
最后,OAuth2.0使得负责处理的OAuth请求的服务器和处理用户的受权服务器之间的角色有一个干净的分离。更多信息,在上述的文章中详述。
Q:OAuth2服务器群怎么使用state来防范CSRF?
A:state只是一个随机的字符串,能够作这样的事情:$state = md5(uniqid(rand(), TRUE));在session中记录satate,以便稍后你能作验证。一些额外的资料:OAuth2威胁文件模型,特别CSRF保护