以业界标杆微信开放平台的网站应用微信登录给第三方授权为例,尝试解答这个问题。先看微信提供的交互流程图:
可以看出,当微信用户同意授权给第三方应用时,会把授权临时票据code以重定向的方式返回给用户,用户浏览器重定向到第三方应用(同时携带code),第三方应用拿这个code,再加上自己的appid和app_secret请求微信开放平台,获取到微信开放平台返回的access_token。之后第三方应用去请求微信开放平台的资源,只要带上这个access_token去访问就好了。这里顺便多提一句,这里的appid和app_secret是第三方应用提前向微信开放平台注册备案的。这里的疑问点是为什么用户同意授权后,不直接返回access_token,而是返回code? 可以从以下思路考量:如果想直接返回access_token,那么需要在用户发起确认授权的那个请求里带上第三方应用的appid和app_secret,这样才能换到access_token。但是app_secret是第三方应用的私钥,不能给到用户的,因为非常危险。所以一个理解重点是,要换取access_token的三要素:用户的同意授权+第三方appid+第三方app_secret。当这三个要素都具备后,才可以获取access_token。因为用户是拿不到第三方appid+第三方app_secret,所以是不可能从用户侧直接获取到access_token的。这个access_token一定需要从第三方应用侧获取。上面是以微信开放平台的方案为例讲解,如果我们不采用微信的app_secret机制,只要传appid就能换access_token出来,此时是否安全呢?这样是不是就可以少了换code再换access_token这个流程?
这个方案下,如果授权后直接返回access_token给用户浏览器的,然后重定向到第三方应用,第三方应用存储这个access_token。这个会有什么问题吗?
问题在于,我这个access_token暴露在用户浏览器了(用户前端),这种方式并不安全,会被窃取。如果把access_token放在第三方应用的server侧进行请求,这样就安全多了,要实现这点,就得有一个授权服务器把access_token告诉第三方应用后台的方式。考虑这些方案:
- 授权服务器主动通知方案。当得到用户授权后,就主动给第三方应用后台发一条消息通知这个access_token,当然这里需要提前注册第三方应用后台的通知的地址。但是即使第三方应用后台拿到这个access_token,他也不知道这个access_token对应的是我平台上的哪个用户。即access_token没法跟第三方平台的用户进行关联。
- code方案。授权后直接返回code给用户浏览器,并携带code重定向给第三方应用后台。此时第三方后台拿到code后,从JWT或者session_id中解析出用户在第三方应用的uid等信息(因为此时用户处于第三方平台的登录态中),这样code和第三方应用的uid就对应上了,此时拿着code去请求access_token,拿到的access_token就是已知uid的access_token。这样一对比,即使是在无app_secret机制的场景下,code方案也是更为合理的。
链接:https://www.zhihu.com/question/27446826/answer/2916005175
标签:OAuth2,用户,access,token,code,应用,第三方 From: https://www.cnblogs.com/leifonlyone/p/18391380