JJWT的简单应用(后端jjwt,过滤器;前端axios,vue2)

1 ,后端JJWT类

package com.utils;

import com.entity.User;
import io.jsonwebtoken.*;

import java.util.Date;

public class JwtUtils {

    /**
     * 签名需要的私有密钥
     */
    private static final String SECRET = "myScrect";


    /**
     * 重载createJwt,通过用户信息和生成Jwt
     * @param user 用户信息
     * @return token
     */
    public static String createJwt(User user) {
        return createJwt(user,1000*60*60);
    }

    /**
     * 通过用户信息和过期时间生成Jwt
     * @param user 用户信息
     * @param ttlMillis 过期时间
     * @return token
     */
    public static String createJwt(User user, long ttlMillis) {
        // 签名算法 HS256,即jjwt已经封装header中需要的算法名称
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        // 生成Jwt的时间,即签发时间
        long nowMillis = System.currentTimeMillis();
        //构建Jwt
        JwtBuilder builder = Jwts.builder()
                //jwt的唯一标识
                .setId(String.valueOf(user.getId()))
                //jwt面向用户
                .setSubject(user.getUname())
                //jwt的签发者
                .setIssuer("aaa")
                //jwt的签发时间
                .setIssuedAt(new Date(nowMillis))
                //设置签名使用的签名算法和签名使用的秘钥
                .signWith(signatureAlgorithm,SECRET);
        //自定义payload的claim信息
        builder.claim("root", "root");
        // 设置过期时间,需要大于签发时间
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            builder.setExpiration(new Date(expMillis));
        }
        String token = builder.compact();
        return token;
    }

//token过期则抛出异常
public static void parseJwt(String jwt){
        //解析jwt
    JwtParser parser = Jwts.parser();
    Claims claims;
    //获取解析后的对象
    claims = Jwts.parser()
            //设置签名秘钥,和生成的签名的秘钥一模一样
            .setSigningKey(SECRET)
            //设置需要解析的jwt
            .parseClaimsJws(jwt)
            .getBody();
    }
}

2,后端过滤器类

import utils.JwtUtils;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

public class LoginFilter implements Filter{
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void destroy() {

    }

    //    白名单
    private List<String> whiteList= Arrays.asList(
            "/",
            "/user"
    );
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request=(HttpServletRequest) servletRequest;
        HttpServletResponse response=(HttpServletResponse) servletResponse;
//    获取请求路径
        String currentUrl=request.getServletPath();
//    白名单放行,遍历白名单
        for (String url:whiteList){
            if (url.contains(currentUrl)){
                filterChain.doFilter(servletRequest, servletResponse);
                return;
            }
        }
//    获取token
        String token=request.getHeader("Authorization");
        try {
            JwtUtils.parseJwt(token);
//    捕获token异常
        } catch (Exception e) {
//    token过期,重定向到一个error处理页面
            response.sendRedirect("/user/error");
        }
//    token有效,放行
        filterChain.doFilter(servletRequest, servletResponse);
    }
}

3,前端axios文件夹下index.js(作用为设置请求头)

import store from "@/store";

import Axios from "axios";

// 重写axios请求基地址

const axios = Axios.create({

  baseURL: "http://localhost:8080/demo_war_exploded/",

  timeout: 60000, //改成60s

});

// axios请求拦截器。当请求地址不为/user且vuex中已存入token,设置请求头,存入token给后端验证

axios.interceptors.request.use(function (config) {

  if (config.url !== "user" && store.getters.getToken) {

    config.headers.Authorization = store.getters.getToken;

  }

  // 请求地址为/user或vuex内未存token,直接返回config对象,后端进行判断处理

  return config;

});

export default axios;

4,前端store文件夹下的index.js(定义及存取token)

import Vue from "vue";

import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({

  state: {

    token: "",

  },

  getters: {

    setToken(state, res) {

      state.token = res;

    },

    getToken(state) {

      return state.token || null;

    },

  },

  mutations: {},

  actions: {},

  modules: {},

});

5,登录页面发送的axios get请求(记得引入store到登录页面)

doGet("user", {

          uname: this.user.uname,

          pwd: this.user.pwd,

        }).then((res) => {

          // 存入token至vuex

          store.state.token = res.data.data.token;

          this.$router.push({ path: "/city" });

        });

6,main.js文件(在头部视项目情况引入对应文件)

// element-ui的引入

import ElementUI from "element-ui";

import "element-ui/lib/theme-chalk/index.css";

import Vue from "vue";

import App from "./App.vue";

import router from "./router";

// 这里我引入了阿里妈妈的图标库

import "./static/css/iconfont.css";

// 引入store

import store from "./store";

Vue.config.productionTip = false;

Vue.use(ElementUI);

new Vue({

  router,

  store,

  render: (h) => h(App),

}).$mount("#app");

// 前置导航守卫,如果页面不是跳转去登录页面并且没有存入token。则跳转回首页

router.beforeEach((to, from, next) => {

  if (store.getters.getToken || to.path.startsWith("/login")) {

    next();

  } else {

    next("/");

  }

});

7,附加内容:

7-1,多次点击登录的报错解决

import CityView from "@/views/CityView.vue";

import Vue from "vue";

import VueRouter from "vue-router";

import LoginView from "../views/LoginView.vue";

Vue.use(VueRouter);

const routes = [

  // 登陆路由

  {

    path: "/",

    name: "login",

    component: LoginView,

  },

  // city数据展示路由

  {

    path: "/city",

    component: CityView,

  },

];

const router = new VueRouter({

  routes,

});

// 防止连续点击多次路由报错

let routerPush = router.push;

let routerReplace = router.replace;

// push方法的处理

router.push = function push(location) {

  return routerPush.call(this, location).catch((err) => err);

};

// replace方法的处理

router.replace = function push(location) {

  return routerReplace.call(this, location).catch((err) => err);

};

export default router;

7-2 User实体类

import lombok.Data;
import java.io.Serializable;

@Data
public class User implements Serializable {

    private Integer id;
    
    private String uname;
    
    private String pwd;

}

7-3 UserVo类(继承自user类)

import lombok.Data;

@Data
public class UserVo extends User{
    private String token;
}

  • 21
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值