OAuth2.0 里面的 state 参数是干什么的?
1.OAuth 2.0 的四种方式
-
授权码
常见于个人用户第三方登录,比如通过微信、QQ、钉钉登录第三方应用。获取临时的access_token
-
隐藏式
见于没有后端的web应用
-
密码式
信任的应用,暴漏密码,由第三方应用去模拟登录
-
凭证式
常见于应用对应用。分发给应用clientId和clientSecret来实现。
第一种和第四种是较为常见的形式。
2.拿钉钉的第三方应用统一授权来举例
-
钉钉开发者后台添加应用,为应用分配钉钉登录功能,配置回调地址;为应用分配相应的人员以及通讯录权限。
-
配置钉钉授权登录地址
详细文档可参考钉钉开发文档
https://login.dingtalk.com/oauth2/auth?
redirect_uri=
&response_type=code
&client_id=
&scope=openid
&state=
&prompt=consent
各个参数的意义:
redirect_uri:就是在开发者后台所填的回调地址
client_id:就是开发者后台的应用标识
state:跟随authCode原样返回。
3.state的意义
回到正题,来说一下state参数的意义。我们可以看到,钉钉开发文档中,说这个参数可以原样返回。如果原样返回,那是不是多此一举呢?那传这个参数的意义是什么呢?
答:是为了防止CSRF 攻击。
啥是CSRF 攻击?(看官们肯定都已经知道了,我这里就是为我自己这个菜鸡做一个笔记)
CSRF(Cross-site request forgery),中文名称:跨站请求伪造。你这可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。
那state是怎么防止CSRF攻击的呢?
你是用户a,你此时去访问第三方网站,调起推特的第三方授权登录,点击同意后,跳转到事先配置好的调转地址,也就是第三方网站的相应地址,第三方网站通过code做好获取临时授权码,和你在第三方网站的用户信息做好绑定映射。
以上,是一个正常的第三方登录流程。
但是,第三方网站上的映射关系可能被攻击者利用,问题就出在你在用你的信息登录时,无法保证第三方应用跳转获取临时授权码是同一次。这样你在第三方网站上,你的绑定映射关系就可能关联了别人。
state参数在第三方授权成功后,会通过跳转地址一同返回给第三方网站,第三方网站收到请求后,通过state参数,知道了是哪一个用户的申请,杜绝了上面说到的情况。
更详细可以参考OAuth2.0官方文档关于授权码授权中关于state参数的介绍以及state参数CRSF的介绍