基于jwt的登录验证

什么是jwt?

JWT:JSON Web Token,作为JSON对象在各方之间传输安全信息,该信息可以被验证和信任,因为它是数字签名的。在前后端分离的项目中,用户需要被授权才可进行某些操作,这就需要jwt的应用。且使用jwt可以减少频繁查询数据库,减轻服务器压力。

大体思路

  • 前端发起登录请求,后端接收到用户信息
  • 后端验证用户信息成功后,为前端返回一个token值
  • 前端回调函数接收到token后,将其存储到vuex和localStorage中
  • 前端每次路由跳转,都需要携带token发起验证

如何实现?

  1. 后端(Java)需要分别实现两个方法:createToken(创建)和checkToken(验证),一般将其封装为静态的工具类。token的有效期由该类定义。
public class JwtUtil {

    private static long time = 1000 * 60 * 60 * 24;//token有效期:24小时
    private static String signature = "admin";

    public static String createToken() {
        JwtBuilder jwtBuilder = Jwts.builder();
        String jwtToken = jwtBuilder
                //header
                .setHeaderParam("typ", "JWT")
                .setHeaderParam("alg", "HS256")
                //payload
                .claim("username", "admin")
                .claim("role", "admin")
                .setSubject("admin-test")
                .setExpiration(new Date(System.currentTimeMillis() + time))
                .setId(UUID.randomUUID().toString())
                //signature
                .signWith(SignatureAlgorithm.HS256, signature)
                .compact();
        return jwtToken;
    }

    public static boolean checkToken(String token) {
        if (token == null) {
            return false;
        }
        try {
            Jws<Claims> claimsJws = Jwts.parser().setSigningKey(signature).parseClaimsJws(token);
        } catch (Exception e) {
            return false;
        }
        return true;
    }
    
}
  1. 后端分别为前端提供两个API:/login和/checkToken,分别用于返回token(登录时)以及验证token
    @PostMapping("/login")
    public LoginResult login(@RequestBody User user) {
        User result_user = userService.login(user.getUsername(), user.getPassword());
        if (result_user == null) {
            return LoginResult.fail("登录失败,用户名或密码错误");
        } else {
            return LoginResult.success(result_user, JwtUtil.createToken());
        }
    }
    
    @GetMapping("/checkToken")
    public Boolean checkToken(HttpServletRequest request){
        String token = request.getHeader("token");
        return JwtUtil.checkToken(token);
    }
  1. 前端(vue)在vuex中定义token、setToken和getToken方法,setToken时需要将token存储到localStorage中
export default new Vuex.Store({
  state: {
    token: '',
  },
  mutations: {
    //存储token方法
    //设置token等于外部传递进来的值 
    setToken(state, token) {
      state.token = token
      localStorage.token = token //同步存储token至localStorage
    },
  },
  getters: {
    //获取token方法
    //判断是否有token,如果没有重新赋值,返回给state的token
    getToken(state) {
      if (!state.token) {
        state.token = localStorage.getItem('token')
      }
      return state.token
    },
  },
})
  1. 前端使用axios发起登录请求,并在回调函数中接收到后端传回的token,此时调用store中的commit方法存储token
    login() {
      this.$axios
        .post("/login", this.user)
        .then((res) => {
          if (res.data.data != null) {
            this.$store.commit("setToken", res.data.token);
            this.$router.push("/home");
            this.$message({
              type: "success",
              message: "登录成功",
            });
          } else {
            this.$message.error("密码错误或账号不存在");
          }
        })
        .catch(() => {
          this.$message.error("服务器繁忙,请稍后再试");
        });
    },
  1. 前端定义路由守卫,在每一次路由跳转时发起/checkToken请求,验证token是否有效,当token过期时用户就需要重新登录了。
//路由守卫,发起token验证,限制页面访问
router.beforeEach((to, from, next) => {
  //获取token
  let token = store.getters.getToken
  if (token == "") {//如果没有token
    if (to.path == "/") {//如果已经是登录页
      next()
    } else {//否则不是登录页
      next({ path: '/' })//跳转到登录页
    }
  } else {//如果有token,就校验token合法性
    axios({
      url: '/checkToken',
      method: 'get',
      headers: {
        token: token
      }
    }).then((response) => {
      if (!response.data) {
        store.commit("setToken", "")//校验失败,移除token
        next({ path: '/' })
      }
    })
    next()
  }
})
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值