SpringBoot JWT

JWT是一种鉴权机制,实现前后端分离登陆和权限的一种解决方式,用户在登陆之后后端生成token传到前端,以后每次的请求都携带着token到后端验证,如果过期或者失效就要求重新登陆。
具体详情请看:https://blog.csdn.net/weixin_53312997/article/details/126938201

后端如何实现token

首先导个依赖

        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.78</version>
        </dependency>

其次建立一个jwt工具类

import com.alibaba.fastjson.JSON;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Base64;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

/**
 * create by fzg
 * 2021/10/12 9:41
 */

public class JwtUtil {

    private static String TOKEN = "token!Q@W3e4r";

    /*** 生成token * @param map //传入payload * @return 返回token */
    public static String getToken(Map<String,String> map){
        JWTCreator.Builder builder = JWT.create();
        map.forEach((k,v)->{ builder.withClaim(k,v); });
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.HOUR,24*3);
        builder.withExpiresAt(instance.getTime());
        return builder.sign(Algorithm.HMAC256(TOKEN)).toString();
    }/**

    7.整合springboot * 验证token * @param token * @return
     * @return*/
    public static void verify(String token){
        JWT.require(Algorithm.HMAC256(TOKEN)).build().verify(token);
    }


    /*** 获取token中payload * @param token * @return */
    public static DecodedJWT getToken(String token){
        return JWT.require(Algorithm.HMAC256(TOKEN)).build().verify(token);
    }

    // token 获取id
    public static Integer getTokenId(String token){
        DecodedJWT untoken = JwtUtil.getToken(token);
        String payload = untoken.getPayload();
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] bytes = decoder.decode(payload);
        //System.out.println("BASE64解密:" + new String(bytes));
        String str = new String(bytes);
        HashMap hashMap = JSON.parseObject(str, HashMap.class);
        Integer aid = Integer.parseInt(hashMap.get("aid").toString());
        return aid;
    }

    // 解密token
    public static String getClaim(String token, String key) {
        DecodedJWT decodedJWT = JWT.decode(token);
        Claim value = decodedJWT.getClaim(key);
        return value.asString();
    }
}

请求拦截器

import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fzg.common.tool.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * create by fzg
 * 2021/10/12 10:47
 */

public class MyInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtUtil jwtUtil;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // 从前端请求中获取token
        String token = request.getHeader("token");
        Map<String,Object> map = new HashMap<>();
        if (token == null){
            map.put("state",false);
            map.put("msg","token为空");
        }else {
            try {
                JwtUtil.verify(token);
                Integer aid = Integer.parseInt(JwtUtil.getClaim(token,"aid"));
                request.setAttribute("aid",aid);
                return true;
            }catch (TokenExpiredException e){
                map.put("state",false);
                map.put("msg","token已过期!");
            }catch (SignatureVerificationException e){
                map.put("state",false);
                map.put("msg","签名错误!");
            }catch (AlgorithmMismatchException e){
                map.put("state",false);
                map.put("msg","加密算法不匹配");
            }catch (Exception e){
                map.put("state",false);
                map.put("msg","无效token!");
            }
        }

        String json = new ObjectMapper().writeValueAsString(map);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println(json);
        return false;

    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

拦截配置

拦截所有请求,除了用户登陆和注册,其他都需要经过MyInterceptor请求拦截器

import com.fzg.common.interceptor.MyInterceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * create by fzg
 * 2021/10/12 12:02
 */

@Component
public class InceptorConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/user/register")
                .excludePathPatterns("/user/login");
    }
}

跨域配置

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * create by fzg
 * 2021/10/9 10:57
 */

@Configuration
public class CrosConfig implements WebMvcConfigurer {


    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOrigin("*");
        config.addAllowedMethod("*");
        config.addAllowedHeader("*");
        config.addExposedHeader("token");
        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);
        return new CorsFilter(configSource);
    }
}

用户登陆成功后后端将token传到前端

HashMap<String, String> map = new HashMap<>();
map.put("aid",user.getAid().toString());
String token = JwtUtil.getToken(map);

前端的所有请求携带token

//引入axios,进行二次封装
import axios from 'axios'

const requests = axios.create({
    // 配置对象
    //基础路径,发送请求的时候,路径当中会出现api
    baseURL: 'http://localhost:8001',
    // baseURL: 'http://43.142.195.65:8001',
    //代表请求超时的时间5秒
    timeout: 5000,
});

export default requests;
// 前端拿到之后存储到localStorage,
// 发送请求的时候再携带token
export const requestMethodName = (param) => requests({
    url: `/blog/userCancelCollectBlog?blogAid=${param}`,
    method: 'post',
    headers: {
        token: localStorage.getItem('token'),
    }
});

// get请求(例子)
export const queryUserConcernList = (data) => requests({
    url: `/user/queryUserConcernList`,
    method: 'get',
    params: data,
    headers: {
        token: localStorage.getItem('token'),
    }
});

// post请求例子
export const sendMessageToChatObject = (params) => requests({
    url: `/chat/sendMessageToChatObject`,
    method: 'post',
    data: params,
    headers: {
        token: localStorage.getItem('token'),
    }
});
posted @ 2022-11-30 11:54  合起来的彳亍  阅读(44)  评论(0编辑  收藏  举报