货运搬家小程序从0到1(五):JWT 鉴权,拦截器 + ThreadLocal 用户上下文

上篇登录跑通,拿到了 token。这篇解决"token 发出去之后怎么用":拦截器统一验签,业务代码零感知地拿到当前用户。

为什么不用 Spring Security

我的场景:两种角色(USER/DRIVER/ADMIN)、几十个接口、无 OAuth 无 SSO。Spring Security 的过滤器链、SecurityContext、UserDetailsService 那一套,学习成本远超收益。手写一个 JWT 工具 + 一个 MVC 拦截器,总代码不到 200 行 ,每一行都看得懂、改得动。小项目的安全感来自简单,不是来自重量级框架。

三件套:JwtUtil、AuthContext、拦截器

1. JwtUtil:手写 HS256

JWT 结构是 header.payload.signature,HS256 的签名就是 HMAC-SHA256(header + "." + payload, secret)。不引第三方库也能写:

java 复制代码
public static String create(Long userId, String role) {
    String header  = base64("{\"alg\":\"HS256\",\"typ\":\"JWT\"}");
    String payload = base64("{\"uid\":" + userId + ",\"role\":\"" + role
                          + "\",\"exp\":" + (System.currentTimeMillis()/1000 + 7*86400) + "}");
    String sign = hmacSha256(header + "." + payload, SECRET);
    return header + "." + payload + "." + sign;
}

解析时先验签再取 uid/role,过期抛异常。就这么多,没有魔法。

2. AuthContext:ThreadLocal 存当前用户

java 复制代码
public class AuthContext {
    private static final ThreadLocal<Long> UID = new ThreadLocal<>();
    public static void set(Long uid) { UID.set(uid); }
    public static Long uid() { return UID.get(); }
    public static void clear() { UID.remove(); }   // 关键!
}

3. 拦截器:验签 + 放行名单

java 复制代码
public class AuthInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object h) {
        String token = req.getHeader("Authorization");   // "Bearer eyJ..."
        Long uid = JwtUtil.parseUserId(token.replace("Bearer ", ""));
        if (uid == null) { resp.setStatus(401); return false; }
        AuthContext.set(uid);
        return true;
    }
    public void afterCompletion(...) { AuthContext.clear(); }
}

注册时排除公开接口(/api/auth/**、/api/vehicle-types、管理端登录等)。

之后所有 Controller 写起来非常干净:

java 复制代码
@GetMapping("/api/me")
public Result me() {
    return Result.ok(userService.info(AuthContext.uid()));  // 当前用户直接拿
}

三个必踩的坑,提前避开

  1. ThreadLocal 必须 remove :Tomcat 线程是复用的,不清理会串用户------这是隐蔽性最高的线上事故来源。放 afterCompletion 里最保险
  2. 放行名单别用通配符放开整个 /api:宁可逐个加白名单
  3. 过期策略从简:7 天过期 + 过期重登。token 自动续期(refresh token)第一版不需要,别给自己加戏

本篇成果

全站鉴权闭环:前端请求头自动带 token → 拦截器验签 → 业务代码 AuthContext.uid() 直取当前用户。下一篇写整个系统的心脏:订单状态机与下单支付。


相关推荐
Ai-_Man7 小时前
您您这可以把Grok的多个会话比如说。左侧的多个会话一次性导出吗?不是单条会话里面的多次会对话。AI导出鸭
javascript·人工智能·ai·小程序·电脑
光影少年10 小时前
Taro 是如何解析入口配置 app.config.ts 和页面配置的?
微信小程序·小程序·typescript·reactjs·百度小程序·taro
DS小龙哥14 小时前
从呼吸心率到离床报警:60G雷达睡眠仪全栈开发实录(硬件+MQTT+小程序)DIY一台全功能睡眠监护仪
stm32·单片机·嵌入式硬件·物联网·小程序·智能家居
扶风ff17 小时前
练题簿在线免费刷题:刷题、背题、错题复习,一个小程序安排日常备考
学习·小程序
扶风ff17 小时前
练题簿在线免费刷题:共享题库、学习任务、在线考试,岗位培训更方便
学习·小程序
愚公搬代码19 小时前
【愚公系列】《微信小程序项目实战(AI编程+视频图解)》014-莫凡商城小程序项目视图容器组件的应用
微信小程序·小程序·ai编程
程xu袁1 天前
只有一段副歌,AI写歌选小程序、Suno还是海绵音乐?
小程序·suno·ai音乐·ai音乐工具·ai生成音乐·ai写歌工具
专业程序开发源2 天前
springboot生命故事书制作小程序65290-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·mysql·小程序·课程设计
QQ_21696290962 天前
基于微信小程序的智能膳食分析系统
java·大数据·spring boot·微信小程序·小程序·旅游
扶风ff2 天前
求职笔试资料太散?用练题簿在线刷题,按岗位整理练习清单
前端·学习·小程序