使用JWT验证登陆(拦截器实现)

JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。

JSON Web Token由三部分组成,它们之间用圆点(.)连接。这三部分分别是:

  • Header
  • Payload
  • Signature

因此,一个典型的JWT看起来是这个样子的:

xxxxx.yyyyy.zzzzz

 详细了解可查看: 知乎:5分钟带你了解JWT

1.引入jwt的jar包。

  <!--引入JWT-->
  <dependency>
       <groupId>com.auth0</groupId>
       <artifactId>java-jwt</artifactId>
       <version>3.10.0</version>
  </dependency>

2.编写token工具类,其中包含生成token方法 和 验证token方法。

package cn.pjh.everyDay.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Calendar;
import java.util.Map;

public class JWTUtils {

    //加密盐 使用它来加密解密
    private static final String sign = "9jIWOD9idje91@#*9wofj+%5895d123";

    /**
     * 生成token  header.payload.sign
     */
    public static String getToken(Map<String,String> map){
        //生成过期时间
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.SECOND,20);
        
        JWTCreator.Builder builder = JWT.create();
        //将传入进来的参数存入token,比如用户id
        map.forEach((k,v)->{
            builder.withClaim(k,v);
        });
        //生成token使用HMAC256算法
        String token = builder.withExpiresAt(instance.getTime())
                .sign(Algorithm.HMAC256(sign));
        
        return token;
    }

    /**
     * 获取token信息方法
     */
    public static DecodedJWT getTokenInfo(String token){
        //解析token拿出内容,加密的时候使用的什么算法这里就要用什么算法解析(HMAC256)
        DecodedJWT verify = JWT.require(Algorithm.HMAC256(sign)).build().verify(token);
        return verify;
    }
}

3.编写拦截器类

package cn.pjh.everyDay.interceptors;

import cn.pjh.everyDay.common.R;
import cn.pjh.everyDay.utils.JWTUtils;
import com.alibaba.fastjson.JSON;
import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class JWTInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //从请求头中获取token
        String token = request.getHeader("token");
        //如果验证未成功直接拦截,并返回原因
        R r = new R<>();
        try {
            //验证token
            JWTUtils.getTokenInfo(token);
            //验证成功没有异常直接放行
            return true;
        }catch (SignatureVerificationException e){
            e.printStackTrace();
            //签名不对抛出的异常
            r.setCode(0);
            r.setMsg("无效签名");
        }catch (TokenExpiredException e){
            //token过期抛出的异常
            e.printStackTrace();
            r.setCode(0);
            r.setMsg("登陆验证过期");
        }catch (AlgorithmMismatchException e){
            //算法不一致发生的异常
            e.printStackTrace();
            r.setCode(0);
            r.setMsg("登陆异常");
        }

        //转存json字符串通过response打印流返回给客户端
        String r1 = JSON.toJSONString(r);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println(r1);
        return false;
    }
}

4.将拦截器注册到mvc

package cn.pjh.everyDay.config;

import cn.pjh.everyDay.interceptors.JWTInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //mvc配置类中添加拦截器
        registry.addInterceptor(new JWTInterceptor())//需要添加的拦截器类
                .addPathPatterns("/**")//需要拦截的路径
                .excludePathPatterns("user/login");//需要排除的路径
    }
}

5.编写登陆接口()

@PostMapping("/login")
    public R<Map> loginUser(User user) {
        //数据库查找到当前用户
        User u = userService.getById(user);
        //如果查询到数据就登陆成功否则失败
        if (u != null){
            //将需要token存储的信息放入map集合
            Map<String, String> map = new HashMap<>();
            map.put("id", u.getId().toString());
            //通过工具类生成token
            String token = JWTUtils.getToken(map);
            //返回一个当前用户的信息和token的map集合,然后交给前端人员,设置访问时将token设置到请求头里面
            Map<String, Object> r = new HashMap<>();
            r.put("userId", u.getId());
            r.put("username", u.getName());
            r.put("phone", u.getPhone());
            r.put("token", token);
            return R.success(r);
        }
        return R.error("请检查账号或密码");
    }

登陆成功之后前端将返回数据里面的token保存在localStorage或者sessionStorage中,之后每次访问将token设置到请求头里面进行访问。

退出账号则前端直接删除掉本地的token。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值