文章目录
- 概要
- JWT -- 登陆整体流程
- 技术名词
- 具体流程
- 流程小结
概要
苍穹外卖中用户登陆过程,采取基于JWT的token认证流程,并在后续操作中进行权限认证。
JWT – 登陆整体流程
用户点击登陆按钮 -->
前端发送登陆请求 -->
后端查询数据库验证账户和密码 -->
生成JWT -->
返回token -->
前端保存token -->
退出登陆(token自然失效)
技术名词
- JWT
- 拦截器
- 过滤器
具体流程
在这里,当我们需要创建JWT令牌时,我们需要先创建出JWT工具类,我们一般命名为JwtUtil。而对于一个JWT工具类,我们需要包含生成和解析这两个基本功能。
生成
publicstaticStringcreateJwt(StringsecretKey,longttlMillis,Map<String,Object>claims){// 指定使用的签名算法 -- 这里使用HS256SignatureAlgorithmsignatureAlgorithm=SignatureAlgorithm.HS256;// 生成JWT的时间longexpMillis=System.currentTimeMills()+ttlMillis;Dateexp=newDate(expMillis);// 设置JWT的bodyJwtBuliderbuilder=Jwts.bulider().setClaims(claims).signWith(signatureAlgorithm,secretKey.getBytes(StandardCharsets.UTF_8)).setExpiration(exp);returnbulider.compact();}解析
publicstaticClaimsparseJWT(StringsecretKey,Stringtoken){Claimsclaims=Jwts.parser().setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8)).parseClaimsJws(token).getBody();returnclaims;}创建token
在苍穹外卖中,我们一般使用HashMap来存放我们的信息,并通过调用JwtUtil工具类去创建token
Map<String,Object>claims=newHashMap<>();claims.put(JwtClaimsConstant.EMP_ID,employee.getId());Stringtoken=JwtUtil.createJWT(jwtProperties.getAdminSecretKey(),jwtProperties.getAdminTtl(),claims);Tip:这里的properties是我们的配置文件
这样我们就拥有了token,在本次登陆后,前端就持有该token,可以用于后续操作的权限认证,那么我们就需要引入“拦截器”的概念。
拦截器的作用
可理解为,其作用是在Controller执行前插入自己的逻辑,对请求统一处理,而不用在每个controller都编写相同的代码。(另外,拦截器同样能做到存储一些信息)
publicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponse,Objecthandler)throwsException{// 判断拦截到的是Controller还是其他资源if(!(handlerinstanceofHandlerMethod)){// 如果不是动态方法,直接放行 -- css, jsreturntrue;}// 从请求头获取令牌Stringtoken=request.getHander(jwtProperties.getAdminTokenName());// 校验令牌try{log.info("jwt校验:{}",token);Claimsclaims=JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(),token);LongempId=long.valueOf(claims.get(JwtClaimsConstant.EMP_ID.toString());log.info("当前员工id:{}",empId);returntrue;}catch(Exceptionex){response.setStatus(401);returnfalse;}}可见,在上面的代码中我们可以将人员身份认证放到拦截器中,并且在Controller执行前就进行判断,而且拦截器中,我们能将数据放入其中以待这个这次登陆的线程中调用。这样,我们就会用到另外一个知识“ThreadLocal”
ThreadLocal本质不是线程,是一个量,但与线程相关,我们放在将来讨论。
了解完了拦截器,我们还需要了解过滤器。
对于过滤器,我们需要知道过滤器的执行策略:所有的请求都会经过过滤器,对请求和响应做统一处理,所以最适合用来做与业务无关,需要对所有请求生效的事情。
做个对比吧
| 对比项 | Filter | Interceptor |
|---|---|---|
| 属于 | Servlet规范 | Spring MVC |
| 执行位置 | 最早 | Controller前 |
| 是否依赖 Srping | 否 | 是 |
| 常见用途 | 编码,跨域,底层日志,安全认证 | JWT(未使用Spring Security时),权限,业务日志 |
那么,到这就了解完了苍穹外卖中基于JWT的token认证流程。
流程小结
对于用户登陆,我们在苍穹外卖中采取基于JWT的token认证,先通过存放个人信息,用HashMap去存储,并放入claims中,然后调用Jwts这个工具类,去创建token,然后将响应体传给前端,前端保存token的值,放入请求头中,随后在后续调用controller过程中,通过我们创建的拦截器,拦截器从请求头中取出token进行校验,判断权限。