用JWT存储登录token信息

1、相关依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
</dependency>

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.11</version>
</dependency>

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

2、需要JWT加密的实体类

import lombok.Data;

import java.io.Serializable;

/**
 * 会员
 *
 * @TableName member
 */

@Data
public class MemberLoginResp implements Serializable {
    /**
     * id
     */
    private Long id;

    /**
     * 手机号
     */
    private String mobile;

    /**
     * token
     */
    private String token;

}

3、编写JWT工具类

public class JwtUtil {
    private static final Logger LOG = LoggerFactory.getLogger(JwtUtil.class);

    /**
     * 盐值很重要,不能泄漏,且每个项目都应该不一样,可以放到配置文件中
     */
    private static final String key = "qjb12306";

    public static String createToken(Long id, String mobile) {
        GlobalBouncyCastleProvider.setUseBouncyCastle(false);
        DateTime now = DateTime.now();
        DateTime expTime = now.offsetNew(DateField.HOUR, 24);
        Map<String, Object> payload = new HashMap<>();
        // 签发时间
        payload.put(JWTPayload.ISSUED_AT, now);
        // 过期时间
        payload.put(JWTPayload.EXPIRES_AT, expTime);
        // 生效时间
        payload.put(JWTPayload.NOT_BEFORE, now);
        // 内容
        payload.put("id", id);
        payload.put("mobile", mobile);
        String token = JWTUtil.createToken(payload, key.getBytes());
        LOG.info("生成JWT token:{}", token);
        return token;
    }

    /**
     * 该函数用于校验JWT(token)的有效性。
     * 首先通过JWTUtil.parseToken解析token,然后使用setKey设置密钥
     * @param token
     * @return 返回校验结果
     */
    public static boolean validate(String token) {
        GlobalBouncyCastleProvider.setUseBouncyCastle(false);
        JWT jwt = JWTUtil.parseToken(token).setKey(key.getBytes());
        // validate包含了verify,通过validate方法校验token的有效性
        boolean validate = jwt.validate(0);
        LOG.info("JWT token校验结果:{}", validate);
        return validate;
    }

    /**
     * 根据提供的token解析并获取JSON对象。
     * 该方法会去除payload中的特定字段(如颁发时间、过期时间、不可早于时间)。
     *
     * @param token 待解析的JWT token字符串。
     * @return 解析后去除特定字段的payload内容,作为JSONObject返回。
     */
    public static JSONObject getJSONObject(String token) {
        GlobalBouncyCastleProvider.setUseBouncyCastle(false);
        JWT jwt = JWTUtil.parseToken(token).setKey(key.getBytes());
        JSONObject payloads = jwt.getPayloads();
        payloads.remove(JWTPayload.ISSUED_AT);
        payloads.remove(JWTPayload.EXPIRES_AT);
        payloads.remove(JWTPayload.NOT_BEFORE);
        LOG.info("根据token获取原始内容:{}", payloads);
        return payloads;
    }

    // 工具测试,可删除
    public static void main(String[] args) {
        createToken(1L, "123");

        String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYmYiOjE3MTQ1NTMxNjEsIm1vYmlsZSI6IjEyMyIsImlkIjoxLCJleHAiOjE3MTQ2Mzk1NjEsImlhdCI6MTcxNDU1MzE2MX0.P67OrNd9SCv0zOfxoLlbsooVHdxPZ-N-gCgDK1E2-F0";
        validate(token);

        getJSONObject(token);
    }
}

在服务层 调用 JwtUtil 生成 token 并返回给前端

String token = JwtUtil.createToken(memberLoginResp.getId(), memberLoginResp.getMobile());

4、保存登录信息到本地线程

context 包下 创建 LoginMemberContext 类保存登录信息

public class LoginMemberContext {
    private static final Logger LOG = LoggerFactory.getLogger(LoginMemberContext.class);

    private static ThreadLocal<MemberLoginResp> member = new ThreadLocal<>();

    public static MemberLoginResp getMember() {
        return member.get();
    }

    public static void setMember(MemberLoginResp member) {
        LoginMemberContext.member.set(member);
    }

    public static Long getId() {
        try {
            return member.get().getId();
        } catch (Exception e) {
            LOG.error("获取登录会员信息异常", e);
            throw e;
        }
    }

}

5、添加拦截器

获取前端请求头中的 token 值解析 token 后传入本地线程变量中

/**
 * 拦截器:Spring框架特有的,常用于登录校验,权限校验,请求日志打印
 */
@Component
public class MemberInterceptor implements HandlerInterceptor {

    private static final Logger LOG = LoggerFactory.getLogger(MemberInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取header的token参数
        String token = request.getHeader("token");
        if (StrUtil.isNotBlank(token)) {
            LOG.info("获取会员登录token:{}", token);
            JSONObject loginMember = JwtUtil.getJSONObject(token);
            LOG.info("当前登录会员:{}", loginMember);
            MemberLoginResp member = JSONUtil.toBean(loginMember, MemberLoginResp.class);
            LoginMemberContext.setMember(member);
        }
        return true;
    }

}

6、在 Spring MVC中添加拦截器

@Configuration
public class SpringMvcConfig implements WebMvcConfigurer {
    @Resource
    MemberInterceptor memberInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        registry.addInterceptor(memberInterceptor)
                .addPathPatterns("/**");
    }
}

7、使用

log.info("从本地线程中获取token {}", LoginMemberContext.getMember());
  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
如果您下载了本程序,但是该程序存在问题无法运行,那么您可以选择退款或者寻求我们的帮助(如果找我们帮助的话,是需要追加额外费用的)。另外,您不会使用资源的话(这种情况不支持退款),也可以找我们帮助(需要追加额外费用) 微信小程序是腾讯公司基于微信平台推出的一种轻量级应用形态,它无需用户下载安装即可在微信内直接使用。自2017年正式上线以来,小程序凭借其便捷性、易获取性和出色的用户体验迅速获得市场认可,并成为连接线上线下服务的重要桥梁。 小程序的核心特点包括: 零安装:用户只需通过微信扫一扫或搜索功能,即可打开和使用小程序,大大降低了用户的使用门槛和手机存储空间压力。 速度快:加载速度相较于传统的HTML5网页更快,依托于微信强大的基础设施,能够实现近乎原生应用的流畅体验。 跨平台兼容:开发者一次开发,即可在多种终端设备上运行,免除了复杂的适配工作,大大提高了开发效率。 社交属性强:小程序可以无缝嵌入微信生态,支持分享至聊天窗口、朋友圈等社交场景,有利于用户间的传播和裂变增长。 丰富接口能力:提供丰富的API接口,可调用微信支付、位置服务、用户身份识别等多种功能,方便企业进行商业服务的集成与拓展。 目前,微信小程序已经覆盖了电商购物、生活服务、娱乐休闲、教育学习、工具助手等多个领域,为数以亿计的用户提供便捷的服务入口,也为众多商家和开发者提供了新的商业模式和创业机会。随着技术的不断升级和完善,小程序已成为现代移动互联网生态中不可或缺的一部分。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值