前言

在之前有写过几篇SpringSecurity前后端不分离架构情况下的认证文章,那么随着现在技术的发展用户上网的方式已经不是过去单纯的浏览器,现在很多应用都实现了APP化,还有随着现在互联网技术的发展,传统的前后端不分离的的项目部署方案已经悄然落下帷幕,而现在较为普及的前后端分离的部署方案更受互联网公司的青睐!

前后端不分离的相关文章

  1. SpringSecurity基本概念入门
  2. SpringSecurity表单认证
  3. SpringSecurity表单认证源码流程分析
  4. SpringSecurity认证的结果在请求间共享
  5. SpringSecurity请求中获取用户认证后认证数据
  6. SpringSocial整合QQ授权登录
  7. SpringSocial使用QQ授权登录流程详细分析

建议按照顺序查看相关文章,后续会跟上SpringSocial整合微信授权登录,以及授权流程的源码分析
像之前文章中开发的前后端不分离的项目,登录成功后,用户信息是存在服务器的session中的(包含session持久化Redis),浏览器每次访问我们的服务的时候,每次都会检查浏览器Cookie里面的JSESSIONID是否存在,如果不存在JSESSIONID那么就会在服务器里面创建一个Session,然后把新建的session写到浏览器的Cookie中,这样每次用户操作浏览器发请求的时候服务器都会根据Cookie中的JESSIONID来检验用户身份,这是目前前后端不分离架构下基于服务器Session保存用户信息的一种方式,如下图左边的流程图!
SpringSecurity OAuth开发前后端分离认证框架介绍
那么本章将和过去的文章不一样,采用前后端分离的架构,如图上右边的流程图,用户不在直接通过浏览器直接来访问我们的应用,而是通过其他的载体,如APP、这里右图右侧的分支如(前端采用VUE向下访问Node.js,再由Node.js访问后端服务)模式,那么这种前后端分离的情况下在使用Session和Cookie的模式就会出现一些问题,首先明确一点,在前后端分离的情况下也是可以使用Session和Cookie的,不管客户端采用的是APP还是其他技术只要在发生HTTP请求的时候可以使用Cookie,那么就可以使用Session和Cookie这种方案,但是Session和Cookie这种方案在前后端分离的情况下会存在一定的问题。

前后端分离情况下产生的问题

  1. 开发繁琐(Cookie这种功能是浏览器内嵌好的,不需要而外写很多代码,在前面几篇文章中也并没有过多涉及到Cookie的操作,但是在APP情况下每次启动都需要从新实例化Http客户端,那么每次实例化的时候Cookie都会空的,那么这时就需要前端自己处理之前存储的Cookie,所以开发起来比较麻烦)
  2. 安全性和客户体验差(基于Cookie和Session的方案,实际上验证都是服务器自己做的,请求中包含JSESSIONID那就直接那出来比对一下这个JSESSIONID存不存在,并没有真实的检验身份,那么这就会导致如果你的JSESSIONID被别人知道了,那么别人就可以直接使用你的JSESSIONID发送请求获取你的身份,那么这里为了JSESSIONID的相对安全就会设置Cookie的有效时间,那么这里时间长了不安全,时间短了那就意味着用户需要频繁的登录,那么用户体验就会很差)
  3. 兼容性问题(有些前端技术不支持Cookie,如小程序)
    那么存在上面这些问题,而且当我们程序的访问者不再是单纯浏览器而是一些应用的时候,我们将采用另一种方式来完成用户认证信息的存储,那么这种方式就是采用令牌的方式(Token)其实他的原理和Session的原理差不多,也会是给用户一个唯一的标识,只是在Session的模式下是往Cookie中写入JSESSIONID,而令牌(Token)的方式是直接发给用户一个Token,那么用户每次访问的时候都需要带着Token,而我们的服务器不将用户信息存储在Session中,而是根据用户每次请求带着的Token来判断他是谁,有什么权限,他能干什么,也就是我们的认证和授权的行为不在是基于服务器的Session了,是基于我们发出去的令牌,那么令牌的表现形式就是一个字符串,当采用令牌的的模式前面的三个问的都会的到一定程度的优化解决,那么这种模式下就需要先了解OAuth协议
    SpringSecurity OAuth开发前后端分离认证框架介绍
    在上面SpringSocial相关文章中有详细讲解到OAuth协议,实际生OAuth协议就是在服务提供商和第三方应用之间做这种授权的协议,授权的方式就是通过令牌(Token)那么在我们开发前后端分离的场景里面,我们自己自己开发的服务就是作为服务提供商的角色,那么我们的APP、前端后端分离后单独部署的前端都认为是第三方应用,那么我们自己服务器作为服务提供商只需要给他们发令牌(Token),他们拿令牌(Token)来访问,我们服务器在验证令牌就可以了,我们这编文章就开始围绕SpringSecurity OAuth来开发服务提供商要完成的绝大部分行为,使用SpringSecurity OAuth我们就可以快速搭建服务提供商程序来发令牌、验令牌

SpringSecurity OAuth开发服务提供商

SpringSecurity OAuth开发前后端分离认证框架介绍
那么要实现OAuth协议中服务提供商这个角色他的所有功能,实际上就是实现两个服务器,也就是认证服务器和资源服务器,那么在认证服务器中又需要实现4中授权模式(授权码模式,简化模式,客户端模式,密码模式),通过这4中模式让我们的应用确认用户的身份,以及所拥有的权限,在SpringSecurity OAuth里面实际上已经把这4中模式已经实现了,那么这4中模式实现后我们知道用户身份权限后我们就需要根据这些用户信息生成Token和存储,因为这里需要存起来后面在资源服务器里面根据这个令牌获取相应的用户信息做检验,所以Token不但要生成还要存储,那么实际上Token的生成和存储在OAuth协议中并没有明确的做规定,但是SpringSecurity OAuth中还是提供了一套默认的实现,那么实现4中授权码模式和Token的生成和存储认证服务器的工作就完成了,在来看我们的资源服务器,所谓资源服务器就是要保护我们的资源,在我们的业务场景下我们要保护的资源实际上就是REST服务,那么这里就是采用SpringSecurity过滤器链来完成对REST的保护的,那么这里SpringSecurity OAuth是在SpringSecurity过滤器链上加个OAuth2AuthenticationProcessingFilter,那么这个过滤器他的作用就是从请求中获取我们认证服务器发出去的Token,(因为在调用我们服务的时候请求中都会包含Token),获取到Token后会根据我们在认证服务器中存储Token的存储策略去对应的存储中找到Token信息,然后根据用户信息是否存在,是否有权限来判断是否能访问我们的额资源,这样的话就实现了我们的功能,那么在个场景下面我们实际上是一定让用户走上面的标准的4中授权模式的如我们的短信登录方式和我们的4中标准授权模式是搭不上的,那么我们还需要额外在认证服务器中编写我们直接的授权模式,让用户通过我们自己的认证方式完成认证,图中橙色的部分都是需要我们自己编写,当然REST部分是不需要变动的,保持原有的controller即可

相关文章: