后端Jwt实现Token编码、解码以及axios的request请求头的Token传输方式

news2024/11/19 18:40:03

目录

一、什么是JWT:

二、Jwt的使用:

第一步:引入依赖:

第二步:配置拦截器:JwtInterceptor.java:

其中异常文件ServiceException配置如下:

全局异常文件GlobalException.java文件配置如下:

其中所需的Result配置如下:

第三步:配置拦截设置文件:InterceptorConfig.java:

第四步:配置Token工具类文件:TokenUtils.java:

request.js的axios封装文件为:

文件布局大致如下:


一、什么是JWT:

        JWT是token的一种实现方式,全称是:JSON Wwb Token。简单来讲,Jwt是一种字符串,可以根据用户信息进行相关的编码操作生成带有用户信息的JWT token,我们可以根据这个来判断其信息是否正确或者是否被篡改。

二、Jwt的使用:

首先是后端:

第一步:引入依赖:

		<dependency>
			<groupId>com.auth0</groupId>
			<artifactId>java-jwt</artifactId>
			<version>4.3.0</version>
		</dependency>

第二步:配置拦截器:JwtInterceptor.java:

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.example.cqcrhouduan.Utils.TokenUtils;
import com.example.cqcrhouduan.exception.ServiceException;
import com.example.cqcrhouduan.mapper.UserMapper;
import io.micrometer.common.util.StringUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

@Component
@Slf4j
public class JwtInterceptor implements HandlerInterceptor {

    @Autowired
    private UserMapper userMapper;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if(request.getMethod().equals("OPTIONS"))
        {
            return true;
        }
        String token = request.getHeader("token");
        if (StringUtils.isEmpty(token)) {
            token = request.getParameter("token");
        }
        token = token;
        // 执行认证
        if (StringUtils.isEmpty(token)) {
            throw new ServiceException(401, "无token,请重新登录");
        }
        // 获取 token 中的adminId
        String userId;
        User user;
        try {
            userId = JWT.decode(token).getAudience().get(0);  //解码
        // 根据token中的userid查询数据库
            user = userMapper.getById(Integer.parseInt(userId));
            user = user;
        } catch (Exception e) {
            String errMsg = "token验证失败,请重新登录";
            log.error(errMsg + ", token=" + token, e);
            throw new ServiceException(401, errMsg);
        }
        if (user == null) {
            throw new ServiceException(401, "用户不存在,请重新登录");
        }

        try {
            // 用户密码加签验证 token
            JWTVerifier jwtVerifier =             
            JWT.require(Algorithm.HMAC256(user.getPassword())).build();
            jwtVerifier.verify(token); // 验证token
        } catch (JWTVerificationException e) {
            throw new ServiceException(401, "token验证失败,请重新登录");
        }
        return true;
    }
}
其中异常文件ServiceException配置如下:
import com.example.cqcrhouduan.pojo.Result;
import lombok.Data;

@Data
public class ServiceException extends RuntimeException {
    private int code;
    public ServiceException(String msg){
        super(msg);
        this.code = 500;
    }

    public ServiceException(int code, String msg){
        super(msg);
        this.code = code;
    }
}
全局异常文件GlobalException.java文件配置如下:
import com.example.cqcrhouduan.pojo.Result;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;


//自定义异常
@ControllerAdvice
public class GlobalException {

    @ExceptionHandler(ServiceException.class)
    @ResponseBody
    public Result serviceException(ServiceException e){
        return Result.error(e.getCode(),e.getMessage());
    }
}
其中所需的Result配置如下:
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {
    private Integer code;
    private String msg;
    private Object data;

    public static Result success(Object data){
        return new Result(200,"success",data);
    }

    public static Result success(){
        return new Result(200,"success",null);
    }

    public static Result error(String msg){
        return new Result(500,msg,null);
    }

    public static Result error(Integer Code ,String msg){
        return new Result(Code,msg,null);
    }

}

第三步:配置拦截设置文件:InterceptorConfig.java:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport {
    // 加自定义拦截器JwtInterceptor,设置拦截规则
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(jwtInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/login","/register");
        super.addInterceptors(registry);
    }

    @Bean
    public JwtInterceptor jwtInterceptor(){
        return new JwtInterceptor();
    }
}

第四步:配置Token工具类文件:TokenUtils.java:

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.example.cqcrhouduan.mapper.UserMapper;
import com.example.cqcrhouduan.pojo.User;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;


@Component
@Slf4j
public class TokenUtils {

    private static UserMapper staticAdminService;

    @Resource
    private UserMapper adminService;

    @PostConstruct
    public void setUserService() {
        staticAdminService = adminService;
    }

    /**
     * 生成token
     *
     * @return
     */
    public static String genToken(int adminId, String sign) {
        return JWT.create().withAudience(Integer.toString(adminId)) // 将 user id 保存到 token 里面,作为载荷
                .withExpiresAt(DateUtil.offsetHours(new Date(), 2)) // 2小时后token过期
                .sign(Algorithm.HMAC256(sign)); // 以 password 作为 token 的密钥
    }

    /**
     * 获取当前登录的用户信息
     *
     * @return user对象
     *  /admin?token=xxxx
     */
    public static User getCurrentAdmin() {
        String token = null;
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            token = request.getHeader("token");
            if (StringUtils.isNotBlank(token)) {
                token = request.getParameter("token");
            }
            if (StringUtils.isBlank(token)) {
                log.error("获取当前登录的token失败, token: {}", token);
                return null;
            }
            String userId = JWT.decode(token).getAudience().get(0);
            return staticAdminService.getById(Integer.valueOf(userId));
        } catch (Exception e) {
            log.error("获取当前登录的管理员信息失败, token={}", token,  e);
            return null;
        }
    }
}

然后是前端axios配置:

request.js的axios封装文件为:

import axios from "axios";
import router from "../modules/router.js";

const request = axios.create({
    baseURL:'http://localhost:8080/',  //自己的请求地址
    timeout:30000,
})


// Add a request interceptor
request.interceptors.request.use((config) => {
    config.headers['Content-Type'] = 'application/json;charset=utf-8';
    let user = JSON.parse(localStorage.getItem("userToken") || '{}')
    // console.log(user.token)  //查看token
    config.headers['token'] = user.token
    // config.headers.Authorization = localStorage.getItem("userToken")
    console.log("ok")
    // Do something before request is sent
    return config;
}, error => {
    console.log('request error' + error)
    // Do something with request error
    return Promise.reject(error);
});

// Add a response interceptor
request.interceptors.response.use(response => {
    let res = response.data;
    if (typeof res === 'string'){
        res = res ? JSON.parse(res) : res
    }
    // if(res.code === 401){ //自动跳转
    //     router.push('/')
    // }
    // Any status code that lie within the range of 2xx cause this function to trigger
    // Do something with response data
    return res;
}, function (error) {
    // Any status codes that falls outside the range of 2xx cause this function to trigger
    // Do something with response error
    console.log('response error' + error)
    return Promise.reject(error);
});

export default request

文件布局大致如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1539992.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

海康威视-AIOT的业务转型

海康威视的转型和定位为智能物联网&#xff08;AIoT&#xff09;解决方案和大数据服务的提供商。 公司不仅仅聚焦于其核心的视频监控业务&#xff0c;而且正在积极拓展到新的技术领域和市场。通过专注于物联感知、人工智能、大数据等技术的创新&#xff0c;对未来技术发展方向的…

增强现实(AR)在广告中的力量

The Power of AR in Advertising 写在前面 增强现实&#xff08;AR -Augmented Reality&#xff09;是指借助软件、应用程序和智能手机、平板电脑或耳机等设备&#xff0c;为日常生活添加视觉和音频元素的技术。如今&#xff0c;品牌和广告商可以在营销活动中使用AR&#xff0…

车道线检测论文:《Ultra Fast Structure-aware Deep Lane Detection》

该论文标题为《Ultra Fast Structure-aware Deep Lane Detection》&#xff0c;作者是浙江大学计算机科学与技术学院的Zequn Qin、Huanyu Wang和Xi Li。论文提出了一种新颖的、简单而有效的车道检测方法&#xff0c;旨在解决具有挑战性场景下的车道检测问题&#xff0c;并实现极…

CentOS系统部署YesPlayMusic播放器并实现公网访问本地音乐资源

文章目录 1. 安装Docker2. 本地安装部署YesPlayMusic3. 安装cpolar内网穿透4. 固定YesPlayMusic公网地址 本篇文章讲解如何使用Docker搭建YesPlayMusic网易云音乐播放器&#xff0c;并且结合cpolar内网穿透实现公网访问音乐播放器。 YesPlayMusic是一款优秀的个人音乐播放器&am…

idea使用token方式登录GitHub

总体上分为两大步&#xff1a;1.GitHub生成token。2.idea配置token登录GitHub。 注&#xff1a;idea配置GitHub的前提是本地已经安装了git程序。 一、GitHub生成token 1.登录GitHub 2.进入token创建页面&#xff08;右上角点击头像–>settings–>页面向下滚动左侧菜单栏…

网络上常见的环路指的是什么

人类的创造力与破坏力同样强大"。 网路互通&#xff0c;同样也衍生出纷繁复杂的路由协议和各种因特网服务&#xff0c;以及"网络安全"这个庞大的领域。 这也是为什么说当今所有的网络通讯流量中&#xff0c;80%的资源都被浪费&#xff0c;只有20%被用以有效数…

网络安全实训Day8

写在前面 网络工程终于讲完了。这星期到了网络安全技术部分。 网络安全实训-网络安全技术 网络安全概述 信息安全&#xff1a;所有保障计算机硬件、系统、软件、数据不因有意或无意的行为导致的服务中断、数据损坏或丢失等安全事件的保障技术 网络安全&#xff1a;基于计算机…

CSS的特殊技巧

1.精灵图 使用精灵图核心总结&#xff1a; 1. 精灵图主要针对于小的背景图片使用。 2. 主要借助于背景位置来实现--- background-position 。 3. 一般情况下精灵图都是负值。&#xff08;千万注意网页中的坐标&#xff1a; x轴右边走是正值&#xff0c;左边走是负值&#xf…

Unity 中 苹果眼镜开发入口

1. 文档介绍了Unity对Apple新操作系统visionOS的支持。 2. Unity提供了完善的文档、模板和支持,帮助开发者快速为visionOS开发应用。 3. Unity的跨平台框架AR Foundation和XR Interaction Toolkit可以帮助现有移动和XR应用无缝迁移到visionOS。 4. 在visionOS上,可以利用Uni…

Python 从0开始 一步步基于Django创建项目(3)使用Admin site管理数据模型

本文内容建立在《Python 从0开始 一步步基于Django创建项目&#xff08;2&#xff09;创建应用程序&数据模型》的基础上。 Django提供的admin site&#xff0c;使得网站管理员&#xff0c;能够轻松管理网站的数据模型。 本文首先创建‘管理员账户’&#xff0c;即超级用户…

超快的 AI 实时语音转文字,比 OpenAI 的 Whisper 快4倍 -- 开源项目 Faster Whisper

faster-whisper 这个项目是基于 OpenAI whisper 的模型&#xff0c;在上面的一个重写。 使用的是 CTranslate2 的这样的一个库&#xff0c;CTranslate2 是用于 Transformer 模型的一个快速推理引擎。 在相同精度的情况下&#xff0c;faster-whisper 的速度比 OpenAI whisper …

【2024第十二届“泰迪杯”数据挖掘挑战赛】B题基于多模态特征融合的图像文本检索—解题全流程(持续更新)

2024 年(第 12 届)“泰迪杯”数据挖掘挑战赛B题 解题全流程&#xff08;持续更新&#xff09; -----基于多模态特征融合的图像文本检索 一、写在前面&#xff1a; ​ 本题的全部资料打包为“全家桶”&#xff0c; “全家桶”包含&#xff1a;数据、代码、模型、结果csv、教程…

解决淘宝镜像过期问题 ERR! request https://registry.npm.taobao.org

目录 一、问题描述 二、解决方案 2.1、针对于域名更换解决方案 2.2、针对于证书过期解决方案 三、进行测试 一、问题描述 针对于2022年5月31号和2024年1 月 22 日前的前端项目 npm.taobao.org和旧域名于2021年官方公告域名更换事件&#xff0c;已于2022年05月31日零时起…

【Node.js】全局变量和全局 API

node 环境中没有 dom 和 bom &#xff0c;此外 es 基本上都是可以正常使用的。 如果一定要使用 dom 和bom&#xff0c;可以借助第三方库 jsdom 帮助我们实现操作。npm i jsdom 实例&#xff1a; const fs require(node:fs) const {JSDOM} require(jsdom)const dom new JS…

刷题日记——还是BFS

题目——奇怪的电梯&#xff08;simplified BFS&#xff09; 分析 这题是简化的BFS&#xff08;我一遍就AC了<夸夸自己~~>&#xff09;&#xff0c;照搬之前分析BFS的思路&#xff0c;需要定义这些数据结构&#xff1a; 结构体position&#xff1a;当前位置信息&#x…

遥感影像数据产品级别概述

1986年&#xff0c;美国航空航天局&#xff08;NASA&#xff09;定义了一系列数据处理"级别"&#xff0c;用以区分源于其地球观测系统&#xff08;EOS&#xff09;卫星获取的影像生成的标准数据产品。给定任何数据产品&#xff0c;我们可以根据其级别来判断其在生产过…

力扣爆刷第103天之CodeTop100五连刷1-5

力扣爆刷第103天之CodeTop100五连刷1-5 文章目录 力扣爆刷第103天之CodeTop100五连刷1-5一、3. 无重复字符的最长子串二、206. 反转链表三、146. LRU 缓存四、215. 数组中的第K个最大元素五、25. K 个一组翻转链表 一、3. 无重复字符的最长子串 题目链接&#xff1a;https://l…

C#,图论与图算法,用于检查给定图是否为欧拉图(Eulerian Graph)的算法与源程序

1 欧拉图 欧拉图是指通过图(无向图或有向图)中所有边且每边仅通过一次通路, 相应的回路称为欧拉回路。具有欧拉回路的图称为欧拉图(Euler Graph), 具有欧拉通路而无欧拉回路的图称为半欧拉图。 对欧拉图的一个现代扩展是蜘蛛图,它向欧拉图增加了可以连接的存在点。 这给…

2、事件修饰符、双向绑定、style样式使用、v-for循环遍历、v-if 和 v-show

一、事件修饰符 1、.stop 阻止冒泡事件 给谁加了阻止冒泡事件&#xff0c;谁下面的盒子就不会执行了 <div id"app"><div class"parent" click"log3"><div class"child" click"log2"><button click.…

IAB欧洲发布首张泛欧洲数字零售媒体能力矩阵图

2024年1月18日&#xff0c;互动广告署-欧洲办事处&#xff08;IAB Europe)发布了首张泛欧洲数字零售媒体能力矩阵图。为媒体买家提供的新资源概述了在欧洲运营的零售商提供的现场、场外和数字店内零售媒体广告机会。 2024年1月18日&#xff0c;比利时布鲁塞尔&#xff0c;欧洲领…