• JavaWeb后端开发 JWT令牌解析 登录校验 通用模板/SpringBoot整合


    目录

    实现思路

    会话跟踪的三个方案--引出Jwt令牌技术

    1.访问cookie的值,在同一会话的不同请求之间共享数据

    2.session

    3.现代普遍采用的令牌技术--JWT令牌

    JWT令牌技术

    ​第一步--生成令牌

    1.引入依赖

    2.生成令牌

    第二步--校验令牌

    第三步--登录下发令牌


    需要解决的问题:用户在未登录状态下,也可以通过访问网址直接跳过登录界面

    实现思路

            通过登录成功的标记来检测,在每个接口前做一个标记判断是否登录,若没登录则返回错误信息,并使前端退出

           但这样较为繁琐,因此我们可以通过一种统一拦截的技术来拦截所有请求.这涉及到了会话跟踪这一技术.

    会话跟踪的三个方案--引出Jwt令牌技术

    1.访问cookie的值,在同一会话的不同请求之间共享数据

    跨域:只要协议/IP地址/端口三个维度任何一个不同,就是跨域操作

    2.session

    3.现代普遍采用的令牌技术--JWT令牌

    JWT令牌技术

    一个令牌包含三个部分:头/有效载荷/签名:防止令牌被篡改

    核心的两个步骤:

    生成令牌  &  校验令牌

    第一步--生成令牌

    1.引入依赖

    2.生成令牌

    1.签名算法

    2.自定义内容

    3.令牌有效期

    以下为测试样例:

    1. @Test
    2. public void JwtTest()
    3. {
    4. Map claims = new HashMap<>();
    5. claims.put("id", 1);
    6. claims.put("name", "tom");
    7. /*此处负载的内容是id和姓名*/
    8. String jwt = Jwts.builder()
    9. /*设置签名算法*/
    10. .signWith(SignatureAlgorithm.HS256, "theresa")
    11. /*自定义内容(负载)*/
    12. .setClaims(claims)
    13. /*设置有效期为一小时*/
    14. .setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000))
    15. .compact();
    16. }

    第二步--校验令牌

    报错的两种情况:过期/被篡改

    .setSigningKey("")填入和开始输入的一样,签名算法
    .parseClaimsJws("")中填入要校验的令牌

    1. public void ParseJwt(String jwt){
    2. //许可验证
    3. Claims claims = Jwts.parser()
    4. .setSigningKey(signKey)//传递签名
    5. .parseClaimsJws(jwt)//传递令牌
    6. .getBody();//得到内容
    7. System.out.println(claims);
    8. }

    第三步--登录下发令牌

    1. @PostMapping("/login")
    2. public Result login(@RequestBody Emp emp){
    3. log.info("员工登录:{}",emp);
    4. Emp e = empService.login(emp);
    5. //若登录成功,生成令牌并下发令牌
    6. if(e != null)
    7. {
    8. //定义claims携带当前登录的员工信息
    9. Map claims = new HashMap<>();
    10. claims.put("id",e.getId());
    11. claims.put("name",e.getName());
    12. claims.put("username",e.getUsername());
    13. ​​​//此处将claims传入了我们第一步定义的生成令牌工具类中
    14. String jwt = JwtUtils.generateJwt(claims);
    15. return Result.success(jwt);
    16. }
    17. //若登录失败,返回错误信息
    18. return Result.error("用户名或密码错误");
    19. }
    20. }

    ThreadLocal不是一个Thread,而是Thread的局部变量
    ThreadLocal为每个线程单独提供一个存储空间,具有线程隔离效果,只有在线程内才能获取到对应的值,线程外则不能访问。
    客户端每一次访问,tomacat都会开辟一个线程
    所以当我们保证在线程的生命周期只内,能访问到,就可以把值放到里面。
    解决原理
    代码中已经提供了封装好的ThreadLocal,名字是BaseContext, 因为每次请求都会用开辟一个线程,而且每次请求前端都会带token过来,所以它发送保存用户的时候也会带token过来进行验证.
    所以将jwt验证出来的token放置在ThreadLocal中
    因为这次保存和他是一个线程,所以ThreadLocal还是一个,所以保存的时候直接从ThreadLocal中获取即可
    解决方式
    在jwt验证的代码中放置token到ThreadLocal
    在service中获取ThreadLocal将id放进去验证

  • 相关阅读:
    R语言实现样本量的估算(2)
    IO_FILE 与高版本 glibc 中的漏洞利用技巧
    如何修炼成“神医”——《OceanBase诊断系列》之一
    vm虚拟机克隆ubuntu
    操作系统 | 内存管理
    从零开始的PICO教程(1)Pico游戏开发项目配置
    isEmpty()与equals()、==“”区别
    Go语言学习(二)-- 基本数据类型
    Zookeeper:实现“命名服务”的 Demo
    前端框架Vue学习 ——(五)前端工程化Vue-cli脚手架
  • 原文地址:https://blog.csdn.net/TheresaApocaly/article/details/132889041