令牌与密码的区别
令牌(token)
与密码(password)
的作用是一样的,都可以进入系统,但是主要有以下几点区别:
令牌 | 密码 | |
---|---|---|
有效时长 | 令牌到期自动失效 | 用户不修改就长期有效 |
谁可撤销 | 数据所有者撤销即失效 | 一般不允许他人撤销 |
权限范围 | 令牌具有权限范围,可限制操作 | 一般为完整权限 |
注:只要知道了令牌,就能进入系统。系统一般不会再次确认身份,所以令牌必须保密,泄漏令牌与泄漏密码的后果是一样的。 这也是为什么令牌的有效期,一般都设置得很短的原因。
认证流程
![OAuth2.0运行流程](https://i-blog.csdnimg.cn/blog_migrate/7100144b906f1bdaa628a868a9c7f325.png)
(A)用户打开客户端以后,客户端要求用户给予授权。
(B)用户同意给予客户端授权。
(C)客户端使用上一步获得的授权,向认证服务器申请令牌。
(D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
(E)客户端使用令牌,向资源服务器申请获取资源。
(F)资源服务器确认令牌无误,同意向客户端开放资源。
也可参考下图帮助理解。
举例
模拟用户使用第三方微信登录京东的授权认证过程
准备工作:
在京东支持微信第三方登录之前,京东需要在微信开放平台上注册,微信给京东发放一个client_id
以及 app secert
的密钥
流程:
-
用户访问京东官网进行登录,跳转到登录页面,此时京东要求用户授权
-
此时用户选择第三方微信登录,会跳转到如下链接。并显示一个提供用户扫码登陆的二维码。用户需要同意登录,生成code
https://open.weixin.qq.com/connect/qrconnect?appid=wx827225356b689e24&state=45451A684ED6970EEE1692B2C496DB7DDF432EBC9B5C30CAC583E22FA6391A2B37D033535639574F25A84B9DDDC72546&redirect_uri=https%3A%2F%2Fqq.jd.com%2Fnew%2Fwx%2Fcallback.action%3Fview%3Dnull%26uuid%3Db37301f413f74cac980757a5d3b885b9&response_type=code&scope=snsapi_login#wechat_redirect
其中主要有以下几个参数
appid: 客户端id state: 表示客户端当前状态 redirect_uri:https%3A%2F%2Fqq.jd.com%2Fnew%2Fwx%2Fcallback.action%3Fview%3Dnull%26uuid%3Db37301f413f74cac980757a5d3b885b9 response_type: code //代表采用授权码模式进行授权 scope: snsapi_login#wechat_redirect //申请的权限范围
此时用户需要做的就是扫码登录
-
假如用户登录成功,那么微信的授权服务器会重定向回客户端的URI,并附上一个授权码(code)和之前提供的本地状态(state)
https://qq.jd.com/new/wx/callback.action?view=null&uuid=b37301f413f74cac980757a5d3b885b9&code=001y0oyV0nwdq229vKzV05pdyV0y0oyA&state=45451A684ED6970EEE1692B2C496DB7DDF432EBC9B5C30CAC583E22FA6391A2B37D033535639574F25A84B9DDDC72546
主要参数有
uuid: b37301f413f74cac980757a5d3b885b9 code: 生成的code,用于下一步获取tokenn
-
京东收到授权码后,附上最先重定向的URI,向微信授权服务器申请令牌,此时的请求参数包含
client_id:在微信开放平台申请的应用 ID client_secret:在微信开放平台申请时提供的APP Secret grant_type:需要填写authorization_code code:上一步获得的 code redirect_uri:回调地址,需要与注册应用里的回调地址以及第一步的 redirect_uri 参数一致
总之简化后的步骤就是:京东拿到用户登录授权成功后的 code 码,请求微信授权服务器换取token。响应可参考
{ "access_token": "ACCESS_TOKEN",//Token 的值 "expires_in": 1234,//过期时间 "uid":"12341234"//当前授权用户的UID。 }
-
最终京东使用获取到的token去请求微信开发的资源
四种授权方式
-
授权码(authorization-code)
第三方应用先申请一个授权码,然后再用该码获取令牌。
-
隐藏式(implicit)
允许直接向前端颁发令牌。这种方式没有授权码这个中间步骤,所以称为(授权码)“隐藏式”(implicit)
-
密码式(password)
如果你高度信任某个应用,RFC 6749 也允许用户把用户名和密码,直接告诉该应用。该应用就使用你的密码,申请令牌,这种方式称为"密码式"(password)。
-
客户端凭证(client credentials)
适用于没有前端的命令行应用,即在命令行下请求令牌。
第一步,A 应用在命令行向 B 发出请求。
https://oauth.b.com/token? grant_type=client_credentials& client_id=CLIENT_ID& client_secret=CLIENT_SECRET
上面 URL 中,
grant_type
参数等于client_credentials
表示采用凭证式,client_id
和client_secret
用来让 B 确认 A 的身份。第二步,B 网站验证通过以后,直接返回令牌。
这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。
注:不管哪一种授权方式,第三方应用申请令牌之前,都必须先到系统备案,说明自己的身份,然后会拿到两个身份识别码:客户端 ID(client ID)和客户端密钥(client secret)。这是为了防止令牌被滥用,没有备案过的第三方应用,是不会拿到令牌的。
参考
https://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html