SpringBoot整合JWT+Vue

  • 引入pom
       <!--引入JWT-->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.10.0</version>
        </dependency>
  • 编写工具类
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;

/**
 * @Description: JWT工具类
 */
public class JWTUtils {
    //秘钥
    private static final String SIGNATURE = "aef7aaf174fa0143ce765a7efd869313";
    //过期时间为1天
   public static  final Integer EXPIRATION_TIME= 1* 24 * 60 * 60;



    /**
     * 生成token
     * @param payload token需要携带的信息
     * @return token字符串
     */
    public static String getToken(Map<String,String> payload){
        // 指定token过期时间为1天
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, EXPIRATION_TIME);
        JWTCreator.Builder builder = JWT.create();
        // 构建payload
        payload.forEach((k,v) -> builder.withClaim(k,v));
        // 指定过期时间和签名算法
        return  builder.withExpiresAt(calendar.getTime()).sign(Algorithm.HMAC256(SIGNATURE));
    }




    /**
     * 验证token
     * @param token
     */
    public static void verify(String token){
        JWT.require(Algorithm.HMAC256(SIGNATURE)).build().verify(token);
    }

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

}


/**
 * 状态码枚举
 */
public enum CodeEnum {

    /**操作成功**/
    SUCCESS(200,"操作成功"),
    /**服务调用异常**/
    SERVICE_CALL_EXCEPTION(400,"服务调用异常"),
    /**操作失败**/
    ERROR(500,"操作失败"),
    /**参数不合法**/
    ILLEGAL_PARAMETER(5001,"参数不合法"),
    /**验证码已失效**/
    VERIFICATION_CODE_FAILURE(5002,"验证码已失效"),
    /**用户昵称重复**/
    DUPLICATE_NICKNAME(5003,"用户昵称重复"),
    /**用户名或密码错误**/
    LOGIN_FAILED(5004,"用户名或密码错误"),
    /**文件上传失败**/
    FILE_UPLOAD_FAILED(5005,"文件上传失败"),
    /**资源不存在*/
    RESOURCE_DOES_NOT_EXIST(5006,"资源不存在"),
    /**无效签名**/
    JWT_INVALID(2001,"无效签名"),
    /**token过期**/
    JWT_OVERDUE(2002,"token过期"),
    /**token算法不一致**/
    JWT_ALGORITHM_INCONSISTENCY(2003,"token算法不一致"),
    /**token失效**/
    JWT_LOSE_EFFECT(2004,"token失效"),
    /**非法请求**/
    ILLEGAL_REQUEST(2005,"非法请求,请求来源不合法");

    /**
     * 自定义状态码
     **/
    private Integer code;
    /**自定义描述**/
    private String message;

    CodeEnum(Integer code, String message){
        this.code = code;
        this.message = message;
    }

    public Integer getCode() {
        return code;
    }
    public String getMessage() {
        return message;
    }
}

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 请求信息类,用于返回请求是否成功
 * @param <T>
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult<T>{
    /**
     * 响应状态码
     */
    private int code;

    /**
     * 响应结果描述
     */
    private String message;

    /**
     * 返回的数据
     */
    private T data;

    /**
     * 成功返回
     * @param data
     * @param <T>
     * @return
     */
    public static <T> CommonResult<T> success(T data) {
        CommonResult<T> response= new CommonResult<>();
        response.setCode(CodeEnum.SUCCESS.getCode());
        response.setMessage(CodeEnum.SUCCESS.getMessage());
        response.setData(data);
        return response;
    }

    /**
     *  失败返回,自定义code
     * @param code
     * @param message
     * @param <T>
     * @return
     */
    public static <T> CommonResult<T> fail(Integer code, String message) {
        CommonResult<T> response = new CommonResult<>();
        response.setCode(code);
        response.setMessage(message);
        return response;
    }

    /**
     *  失败返回
     * @param codeEnum
     * @param <T>
     * @return
     */
    public static <T> CommonResult<T> fail(CodeEnum codeEnum) {
        CommonResult<T> response = new CommonResult<>();
        response.setCode(codeEnum.getCode());
        response.setMessage(codeEnum.getMessage());
        return response;
    }
    /**
     *  失败返回
     * @param message
     * @param <T>
     * @return
     */
    public static <T> CommonResult<T> fail(String message) {
        CommonResult<T> response = new CommonResult<>();
        response.setCode(CodeEnum.ERROR.getCode());
        response.setMessage(message);
        return response;
    }

}

  • 编写请求拦截器
import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.example.vehicleinformationsystem.bean.CodeEnum;
import com.example.vehicleinformationsystem.bean.CommonResult;
import com.example.vehicleinformationsystem.util.JWTUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

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

/**
 * @Description: jwt拦截器
 */
@Component
public class JWTInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取请求头中存放的令牌token
        String token = request.getHeader("Authorization");
        CommonResult<CodeEnum> result=new CommonResult();
        try {
            if(StrUtil.isNotBlank(token)){
                //验证令牌
                JWTUtils.verify(token);
                return true;
            }else{
                result.setCode(CodeEnum.JWT_INVALID.getCode());
                result.setMessage(CodeEnum.JWT_INVALID.getMessage());
            }

        } catch (SignatureVerificationException e) {
            e.printStackTrace();

            result.setCode(CodeEnum.JWT_INVALID.getCode());
            result.setMessage(CodeEnum.JWT_INVALID.getMessage());
        } catch (AlgorithmMismatchException e) {
            e.printStackTrace();
            result.setCode(CodeEnum.JWT_ALGORITHM_INCONSISTENCY.getCode());
            result.setMessage(CodeEnum.JWT_ALGORITHM_INCONSISTENCY.getMessage());
        } catch (TokenExpiredException e) {
            e.printStackTrace();
            result.setCode(CodeEnum.JWT_OVERDUE.getCode());
            result.setMessage(CodeEnum.JWT_OVERDUE.getMessage());

        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(CodeEnum.JWT_OVERDUE.getCode());
            result.setMessage(CodeEnum.JWT_OVERDUE.getMessage());
        }


        //将map转为json,返回给前端
        String json = new ObjectMapper().writeValueAsString(result);
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().print(json);
        return false;
    }
}

  • 注册拦截器
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @Description: 注册拦截器
 */

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Autowired
    private JWTInterceptor jwtInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(jwtInterceptor)
                //拦截所有请求
                .addPathPatterns("/**")
                //不需要拦截的请求
                .excludePathPatterns("/system/login","/system/addUser");
    }

}

  • 测试
    1.不携带token
    在这里插入图片描述
    返回结果:
    在这里插入图片描述
    2.携带token

在这里插入图片描述

  • 整合Vue

1.解决跨域问题

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;

/**
解决跨域
 */
@Configuration
public class GlobalCorsConfig {

    @Bean
    public CorsFilter corsFilter() {
        //1.添加CORS配置信息
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOriginPattern("*");
        //2) 是否发送Cookie信息
        config.setAllowCredentials(true);
        //3) 允许的请求方式
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("HEAD");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("DELETE");
        config.addAllowedMethod("PATCH");
        // 4)允许的头信息
        config.addAllowedHeader("*");
        // 4)有效时间
        config.setMaxAge(3600L);

        //2.添加映射路径,我们拦截一切请求
        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);

        //3.返回新的CorsFilter.
        return new CorsFilter(configSource);
    }
}

2.登录成功返回token

 /**
     * 登录
     *
     * @param userInfo
     * @return
     */
    @PostMapping(value = "/login")
    public CommonResult<Map<String,Object>> login(@RequestBody Map<String,Object>  userInfo) {
        if(userInfo!=null){
           		if("admin".equals(userInfo.get("nickName"))&&"admin".equals(userInfo.get("password"))){
           		//设置token需要返回的信息
                    Map<String,String> tokenMap=new HashMap<>();
                    tokenMap.put("id","111");
                    tokenMap.put("nickName",userInfo.get("nickName"));
                    result.put("token",JWTUtils.getToken(tokenMap));

                    return CommonResult.success(result);
           		}
            }

        return CommonResult.fail("用户昵称或密码错误");
    }

3.Vue将登录成功后接收到的token存储在浏览器

//登录请求	
login(this.param).then(res => {
	console.log("登录请求结果--》》", res);
//判断是否登录成功
if (res.code == 200) {
	this.$message.success('登录成功');
	localStorage.setItem('token', res.data.token);
} else {
	this.$message.error('用户昵称或密码错误');
}
});

4.每次请求时,携带token(此处可以在vue编写一个请求前置拦截器,这样携带token这个步骤就可以降低冗余,此处略)

/**
 *删除用户信息
 * @param {*} param 
 */
export const deleteUser = param => {
    return request({
        url: '/system/deleteUser/'+ param,
        method: 'GET',
		headers:{ //向headers中添加token
			Authorization:localStorage.getItem("token")
		}
    });
};
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亿只王菜菜

各位爷,赏口饭吃吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值