OAuth使用场景
我在A网站有一个账户,里面存有我的账户资料和其他信息。我现在第一次到B网站,我想用我在A网站的账户身份登录到B网站。B网站能确认我的身份,但不能得到我在A中的隐私资料。
比如我想用新浪微博账户登录某个游戏APP。然后能登录进去这个游戏,并且游戏能知道我的微博好友谁在玩。
这样的好处:不用在新网站注册新的账户。B网站不会从A网站得到我的密码和其他隐私。
这就是OAuth。现在已经发展到2.0版本了。
怎么实现这个场景
这里有三个角色,A网站、B网站、我自己。 B网站首先会跟我要一个grant授权。然后以此去跟A网站申请token令牌。 A网站会给B网站一个token令牌,以后b网站可以用token来A网站获取有限的数据资源。 A网站为了这一认证过程设置了一个认证服务器Authorization server。
怎么样的一个grant授权?
我自己给B网站一个怎么样的grant授权?既能不告诉他私密信息,又能让A网站能确认我的身份呢?
OAuth 2.0定义了四种授权方式:
- 简化模式(implicit)
- 授权码模式(authorization code)
- 密码模式(resource owner password credentials)
- 客户端模式(client credentials)
在OAuth标准中,A网站的认证服务器叫做Authorization server,B网站叫做client,我自己叫做user。
- 简化模式是最简单的方法,即让我自己去跟A网站要token令牌,然后交给B网站保存。
- 密码模式是最不安全的方法,即让我告诉B网站我的登录密码,然后B网站去申请token。
- 客户端模式是最不像OAuth的方法,即让我先注册B网站,然后B网站再去以自己的名义而不以我的名义申请token。
- 授权码模式是最标准正规的方法。
以QQ互联的OAuth为例:
请求授权码Authorization Code
请求地址:https://graph.qq.com/oauth2.0/authorize
请求方法:GET
请求参数:
- response_type:表示授权类型,此处的值固定为”code”
- client_id:表示客户端的ID,这是腾讯作为A网站给B网站分配的。
- redirect_uri:表示重定向URI,成功授权后的回调地址,必须是注册appid时填写的主域名下的地址,建议设置为网站首页或网站的用户中心。注意需要将url进行URLEncode。
- scope:表示申请的权限范围,可选项
- state:表示客户端的当前状态,用于第三方应用防止CSRF攻击,成功授权后回调时会原样带回。务必严格按照流程检查用户与state参数状态的绑定。state不要设置为固定值,较好的state计算方式是简单随机值+session进行绑定。
返回说明: 如果用户成功登录并授权,则会跳转到指定的回调地址,并在redirect_uri地址后带上Authorization Code和原始的state值。如: http://graph.qq.com/demo/index.jsp?code=9A5F********06AF&state=test
获取token
请求地址:https://graph.qq.com/oauth2.0/token
请求方法:GET
请求参数:
- grant_type:表示使用的授权模式,此处的值固定为”authorization_code”。
- redirect_uri:表示重定向URI,且必须与A步骤中的该参数值保持一致。
- client_id:表示客户端ID,申请QQ登录成功后,分配给网站的appid。
- client_secret:申请QQ登录成功后,分配给网站的appkey。
- code:表示上一步获得的授权码。如果用户成功登录并授权,则会跳转到指定的回调地址,并在URL中带上Authorization Code。 例如,回调地址为www.qq.com/my.php,则跳转到: http://www.qq.com/my.php?code=520DD95263C1CFEA087** 返回说明: 如果成功返回,即可在返回包中获取到Token、token有效期expires_in以及续期token所需的参数refresh_token。
安全事项
- 授权码Authorization Code有效期应该很短。
- token的有效期长一点,但不是无限。
- state状态必须严格检查。