【手摸手,带你搭建前后端分离商城系统】03 整合Spring Security token 实现方案,完成主业务登录

【手摸手,带你搭建前后端分离商城系统】03 整合Spring Security token 实现方案,完成主业务登录

上节里面,我们已经将基本的前端 VUE + Element UI 整合到了一起。并且通过 axios 发送请求到后端API。

解决跨域问题后、成功从后端获取到数据。

本小结,将和大家一起搭建 Spring-Security + token 的方式先完成登录。权限将在后面讲解。

引入

在之前,我们的 API 都是一种裸奔的方式。谁都可以访问,肯定是不安全的。所以我们要引入安全校验框架。

传统 session 方案

传统session 的方式是,通过一个 拦截器 拦截所有的请求,若 cookie 当中存储的 session id 在服务端过期后、则要求前端重新登录,进而获取一个新的session

session 与 cookie 区别

因为HTTP 是一种无状态的协议。所以服务端不知道这个 请求是谁发过来的,有好多人访问服务器,但是对于服务器来说,这些人我都不认识。就需要一种东西来给每个人加一个 ID 。

session(会话) 是一种客户端发起请求后, 服务端用来识别用户的东西,可以保存一些用户的基本信息。比如ID什么的

cookie 是一种客户端浏览器用来记录和保存信息的东西。简单理解,如图所示。

image-20201015110133157

当然,默认的cookie 里面总会包含一串 JSESSIONID

image-20201015110702977

session认证所显露的问题

Session: 每个用户经过我们的应用认证之后,我们的应用都要在服务端做一次记录,以方便用户下次请求的鉴别,通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大。

扩展性: 用户认证之后,服务端做认证记录,如果认证的记录被保存在内存中的话,这意味着用户下次请求还必须要请求在这台服务器上,这样才能拿到授权的资源,这样在分布式的应用上,相应的限制了负载均衡器的能力。这也意味着限制了应用的扩展能力。

CSRF: 因为是基于cookie来进行用户识别的, cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击。

JWT

https://jwt.io/

肯定是原有的session认证的方式存在弊端、我们就需要采取一种新的方式来进行验证。JWT

JWT token 由三部分构成:

头部(header)

载荷(playload)

签证(signature)

具体的内容可以参考: https://www.jianshu.com/p/576dbf44b2ae

头部 header

头部一般包含加密算法和类型。例如

{ "alg": "HS256",// 加密算法 "typ": "JWT" // 声明类型 } 负荷 playload

负载可以理解为存放信息的位置,例如:

{ "iss":"mall-pro", // 签发者 "sub":"admin", // 面向的用户 "iat": 1602737566890,//签发时间 "exp": 1602739566890//过期时间,必须大于签发时间 } 签证(signature)

签证一般是头部和负荷组成内容的,一旦头部和负荷内容被篡改,验签的时候也将无法通过。

//secret为加密算法的密钥 String signature = HMACSHA512(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)

我们来参考一个生成的 JWT 实例

注意,我这里使用回车、一般三部分都是通过标点进行分割的。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ. SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c 实现原理

用户调用登录接口后、验证用户名和密码。验证成功后、颁发给其token

前台获得 token 后,将其存放到本地、每次的请求都将这个token 携带到请求头里面。

后台收到请求后、验证请求头里面的 Authorization 是否正确、从而判断是否可以调用这个接口。

通过解析 token 将账号信息存入 userDetail 让其顺利调用接口信息、并可以在接口中获得当前登录人的账号信息。

Spring Security

安全框架,我们这里考虑使用 Spring-Security ,使用全家桶系列,一般大家都会想到apache shiro 等权限框架、都是可以的。我们这里介绍如何加入 Spring-Security

引入到 mall-security 并且添加一个配置文件。

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> 添加一个登陆接口

我们首先从登陆接口开始,一个最基本的 controller 接受参数。当然,用户名和密码肯定是不能为空的,校验完后交给 service

@ApiOperation("用户登录接口") @RequestMapping("login") public CommonResult login(@RequestBody @Valid @ApiParam("用户名密码") UmsAdminLoginParam param) { UmsAdminTokenBO tokenBO = umsAdminService.umsAdminLogin(param); return CommonResult.success(tokenBO); }

具体的内容无非是:查询数据库、是否存在、密码是否正确。正确就构造一个 token 返回给前端。这里主要说一些重要的点。

断言与全局异常处理

断言可以理解为:若当前行不符合判断条件、则抛出异常。或者直接使用断言来抛出一个异常。比如账号不存在,直接抛出一个异常即可。

全局异常处理:全局异常处理,在全局统一拦截异常信息,并通过{code=500,message="error message"} 的方式返回给前端做出提示即可。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyjdzd.html