oauth2.0第三方授权
本文描述的是按照oauth2.0第三方授权的实践过程。关于什么是oauth2.0,因为相关资源实在太多,不再赘述,如果你还不太理解oauth可以访问这篇文章。
github授权登录
本坑尝试着用微信第三方授权方式练练手,然后微信开发平台要求,使用它们的授权需要有上传一份关于使用授权网站的信息,其中一项是网站的备案信息,显然对于在本地测试了,没有域名和服务器的穷屌丝是没有办法,好在很多可以用于授权的应用很多,github就是其中一个,基本原理也如出一辙。如果要动手微信的第三方授权的盆友可能需要稍微注意一下。github的api是有restfull风格,如果想学习restfull的相关风格后台开发,研究github相关内容可能也会带来帮助。下面进入正题了。
首先到github的setting=> OAuth application => Register a new application注册应用,完成填写相关注册信息后如下:
可以看到的回调链接说明,我们可以对功能进行本地电脑的测试,这边国内其他应用显然要开放一点。
从github官网文档可以得知github的授权的流程是按照oauth2.0协议来的,而且是按照标准流程来实现的。大致流程如下:
1、前端触发事件重定向到官网的授权页面,链接请求需要包括注册的client_id和scope。
2、授权完成后,github又重定向到autorization callback URl,页面浏览器网址链接上code参数。这是第三步骤的授权码。
3、有了授权码,加上client_id,client_secret,code 发送post请求,以此获得access_token。
4、有了access_token,后台就可以继续发送获取用户信息的get请求了。就此完成整个授权和获取信息的过程。
授权流程的调整
通过体验上面的流程来进行授权,我们发现有个感受,就是像code,client_id,access_token都会拼接在重定向或者get请求链接的尾端。很多人可能并不想这样明显的显示授权和用户信息。为此我们需要做一些调整,大致如下:
1、为了维持数据存放习惯,client_id ,scope ,密码等等信息交给后台负责存放,前端发送get请求获取这些信息,组成url,并根据该url重定向到官方的授权页面。
2、用户完成授权后,Authorization callback Url 不再是前端路径,改成后台服务,也就是说官网重定向到后台,后台获取到code授权码。
3、后台获取到code后,就像github api 发送post 请求获取access_token。
4、紧接着,后台通过access_token向github api 索要用户信息。
5、使用cookie或者session保存用户信息,重定向到前端,完成整个授权获取用户信息过程。
通过以上的变化,很多请求参数是后台在进行操作,相关信息将不会明显显示在前端web链接上了,根据需求业务的调整,流程可以进行相关调整。
用户token认证
在实现token认证之前,本坑觉得我们必须先搞懂两个问题:
1、认证与授权有什么区别?
2、 token、cookie、session都会用于认证,并且和用户有关,他们有什么区别?
本坑这篇文章中的授权都是指对应用进行授权,以此实现获取用户信息,完成登录。而认证是指对用户进行甄别许可,是服务器端对客户端的用户的识别。应该比较容易理解。
那么token、cookie、session都可以作为识别用户的工具,又有什么不同呢?
比较这三者,总会提醒我们http是无状态的。犹如两个人打电话,接收方永远不知道到对方是谁,更不知道打电话者打过几次,所以也不知道应不应该答应接收方的一些话。因为这个无状态,就需要这三个工具帮助接电话者解决因为不知道对方是谁而引发的一些问题。
1、cookie 是可以长久保存的用户信息,它由服务器创建,发给客户端,保存在浏览器中,也是硬盘中,客户端每次发送请求时携带cookie发给服务器,让服务器是获取信息从而实现身份识别或者其他功能。
2、session是指会话,值得注意的是本坑所述session是指服务器的session,很多同学容易搞混客户端存在sessionid ,sessionstorge等等。我们常常谈到浏览器窗口关闭,会话就结束了。然而服务器session不会马上消失,不过客户端sessionid 是会马上消失。如果在正常session有效期内再次打开窗口,触发请求,请求中的sessionid已经消失,服务器将再次为它生成一个新的sessionid,服务器也会建立新的session对象与之对应,原来的session用户信息虽然存在,但是如果客户端没信息与原来的session空间建立关系,那么服务器和客户端就会把它当成空气,犹如消失。所以如果后台把相关信息保存到session里,前端一旦关闭页面,不采用其他方法的话,该回话存储的相关信息将会与用户断开联系,虽然它依然存在着。像一般信息往往都存在cookie中,或者及时提交数据库,这样可以更有效的保存数据。
对session来说,cookie有着天生的依存关系。前面所说的session id将以jsessionid的名称保存到cookie中。然而它并不是像cookie一样存在硬盘中,而是内存中,cookie在此就有区分,一个是会话级别cookie,就是包含这个jsessionid;另一个是长久有效cookie。这也是为什么浏览器关闭窗口,对应jsessionid就消失的原因。由于cookie长时间有效存在的特点,往往很容易被盗用。得力于存储在服务器,session有更加高的安全性。大量用session对象来存储也不是什么好事,它不利于服务器的性能。
3、token是通过拼接,加密形成的一个字符串,可长可短,一位用户在一段时间内有个唯一的token,服务器通过token来识别该用户有没有权利来获得服务器的服务。所以服务器不必知道用户信息就可以知道能不能给与服务。token是保存再数据库中的。然而token毕竟不包含用户信息,对于更多的数据会话存储,token可能并不足够,这时候就要使用session来帮忙。所以大部分的应用可能并不仅仅是使用以上方案的其中一个,而是多种并用。
本坑基于express+mogoose来搭建的后台。本坑使用的token生成与验证的轮子是jsonwebtoken,大体上来说只要是服务器提供数据的服务都是要进行token验证的。具体后端验证实现可以apiToken中查看。前端项目地址,后端项目地址
参考资料
OAUTH2.0
VUE开发SPA之较舒服的微信授权登录
浏览器关闭与否和session存在的关系
session与jsessionid的生命周期
session和cookie