当前位置:   article > 正文

Spring+Springmvc+Hibernate结合Jwt实现前后端分离token验证(含源码Demo)_spring mvc集成sa-token

spring mvc集成sa-token

前言

什么是token验证,我第一次听的时候,感觉非常高大上,但实际上形象的理解就是:

比如你去酒店开一间房,那么在前台的人员会给你一张房卡,规定时间内,你可以用这张房卡访问指定的房间,当时间结束后,那么这张房卡就失效了,需要重新在前台申请

那么token就相当于这张房卡,前台就相当于拦截器,拦截所有用户的请求,并发放房卡,没有房卡或者房卡时间超时的不能再访问房间。

那么实现的过程很好理解了,我们首先需要根据用户登录的账号密码来设定token,这个token包含的基本信息有:用户账号密码,token过期时间等,用户登录以后,返回一个token,然后在访问其他url的时候必须在头文件中携带该token,并且需要检查token是否有效,如果有效,就可以请求成功,无效就返回失败。

那么接下来,我们就看一下这个实现过程

token验证后端实现

首先,我们需要一个token的工具类,来帮助我们根据用户信息生成token,并且可以检测token:
这里用到了JWT,具体概念可以看这篇文章:什么是JWT?

public class TokenUtil {
    //设置过期时间
    private static final long EXPIRE_DATE=30*60*100000;
    //token秘钥
    private static final String TOKEN_SECRET = "ZCfasfhuaUUHufguGuwu2020BQWE";

    public static String token (String username,String password){

        String token = "";
        try {
            //过期时间
            Date date = new Date(System.currentTimeMillis()+EXPIRE_DATE);
            //秘钥及加密算法
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            //设置头部信息
            Map<String,Object> header = new HashMap<>();
            header.put("typ","JWT");
            header.put("alg","HS256");
            //携带username,password信息,生成签名
            token = JWT.create()
                    .withHeader(header)
                    .withClaim("username",username)
                    .withClaim("password",password).withExpiresAt(date)
                    .sign(algorithm);
            System.out.println("token:  "+token);
        }catch (Exception e){
            e.printStackTrace();
            return  null;
        }
        return token;
    }

    public static boolean verify(String token){
        /**
         * @desc   验证token,通过返回true
         * @params [token]需要校验的串
         **/
        try {
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT jwt = verifier.verify(token);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return  false;
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

JWT需要导入的依赖:

		<!--JWT-->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.8.2</version>
        </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

然后我们需要在用户登录请求中,为其增加token的生成用户的token信息表,由于一段时间会失效,没有永久保存的必要,可以放在缓存中,常见的就是用redis,这里简化了操作,将token信息存入到数据库的一张表中
在这里插入图片描述
那么我们在登录请求中就同时为该用户生成一个新的token,save或者update到表中:登录成功后就返回token给前端
在这里插入图片描述
好了,现在用户已经有了token,那么我们就需要设定它必须拿此token才能访问内部url,那么就需要拦截器:

public class HeaderTokenInterceptor implements HandlerInterceptor {
    private final static Logger logger= LoggerFactory.getLogger(HeaderTokenInterceptor.class);
    @Override
    public boolean preHandle(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler) throws Exception {
        logger.info("filter running....");
        ResponseData responseData=null;
        //获取我们请求头中的token验证字符
        String headerToken=request.getHeader("token");
        //检测当前页面,我们设置当前页面不是登录注册页面时,对其进行拦截
        //检测url中有没有login字符
        System.out.println("request url  "+request.getRequestURI());
        if(!request.getRequestURI().contains("act")){
            if(headerToken==null) {
                //如果token不存在的话,返回错误信息
                responseData = ResponseData.customerError();
                logger.info("token不存在");
            }
            try {
                // 对token进行更新与验证
                TokenUtil.verify(headerToken);
            } catch (Exception e) {
                // 当token验证出现异常返回错误信息,token不匹配
                responseData=ResponseData.customerError();
            }
        }
        if(responseData!=null) {//如果有错误信息
            response.getWriter().write(JSON.toJSONString(responseData));
            return false;
        }else {
            // 将token加入返回页面的header
            response.setHeader("token", headerToken);
            return true;
        }
    }

    @Override
    public void postHandle(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }
    @Override
    public void afterCompletion(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

好了,到这里就完成了token验证的基本操作,
那么接下来就需要前端的配合

token验证前端实现

前端的任务比较简单,就是将登录返回的token信息存入到sessionStorage或者是cookies
在这里插入图片描述
我这里写的demo是放在了cookies中并在请求的时候取出token
在这里插入图片描述
实际上这个方法并不是很好,因为如果每次请求都要去获取cookie值会比较的麻烦
在前端写一个拦截器,对每一个请求的url都加上当前用户的token会更好。(我是前端小菜,这部分还有些问题,后面会再做修改)
demo的内容如下,很简单,就是模拟用户登录注册和页面访问
当然这是携带token的
在这里插入图片描述
在这里插入图片描述
如果不携带token就会拒绝访问,这里我用postman去调用:
在这里插入图片描述
前后端代码,我已经上传到git上了,有需要的伙伴可以参考:
https://github.com/IsMrChen/Practice/tree/ssh/ssh/houseDemo
在这里插入图片描述

如果文章对你有帮助,不要忘了给我点个赞吼( ̄▽ ̄)~
欢迎关注我的微信公众号:松鼠技术站

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/182360
推荐阅读
相关标签
  

闽ICP备14008679号