百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

若依开发框架解析笔记(7)-jwt的应用

ccwgpt 2024-09-13 16:02 45 浏览 0 评论

这篇讲一下若依框架认证所用的jwt技术。若依前后端分离的框架,不同于以前的单体的web应用的架构,可以把session存储在服务器的内存中,浏览器访问的时候通过cookie携带相关的认证信息,服务器可以去通过cookie里面的值去判断该请求是否已经经过认证。这个 session技术也有一定的弊端,就是session被存储在了服务器内容中,对于内存有较大的压力,并且后台有多个server的情况下,还需要负载均衡有会话保持的功能。

对于session的存储,也有把 session存储在redis中,这样虽然解决了对于服务器内存的压力,和服务器无状态的情况,但是这样使得系统对于redis的依赖也加重了。

由于现在采用了前后端分离的技术,后台服务器不会直接与客户端接触,后台服务器只是会与前端服务器进行交互,一般性的会话保持肯定是不可行的,后端的服务器对于前端发过来的请求肯定是没有保持状态一说了,所以有了不同于session的认证技术了。

若依框架使用了jwt(Json Web Token)技术,来进行登录和鉴权。主要的流程有这么几步:

登录成功之后,服务器端验证通过返回jwt的字符串给客户端
客户端再发起请求之后,会在请求头里面带上jwt的内容
服务器验证jwt中的内容

这个与session的区别在于服务器端不会存储生成的token,服务器负责生成和解析。

我们可以通过浏览器的开发者模式观察一下,登录之后的返回内容:

返回的那个token就是后续用于鉴权使用的。可以看到jwt的格式是一个字符串,用"."分隔成3部分。

若依框架用了jjwt这个库来实现了token的生成和解析。

       <!-- Token生成与解析-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
        </dependency>

首先关注一下工程中配置文件的部分,首先定义了在http请求头中的标识,令牌的密钥,和有效时长。

# token配置
token:
    # 令牌自定义标识
    header: Authorization
    # 令牌密钥
    secret: abcdefghijklmnopqrstuvwxyz
    # 令牌有效期(默认30分钟)
    expireTime: 30

下一步,我们准备分析一下框架里面的源码,主要的关注的功能是两个,一个是生成token,另外一个则是解析。TokenService.java这个类是主要的要关注的。首先是从配置文件中读取token相关的配置。

 // 令牌自定义标识
    @Value("${token.header}")
    private String header;

    // 令牌秘钥
    @Value("${token.secret}")
    private String secret;

    // 令牌有效期(默认30分钟)
    @Value("${token.expireTime}")
    private int expireTime;

createToken这个方法是核心的一个方法,用于生成token,这里很多都是调用了现有的一些工具,我们主要关注一下实现的流程。首先产生一个随机id,然后再进行一些登录信息的设置,然后再更新token,最后调用jwt 的工具生成token,签名算法是 HS512

    /**
     * 创建令牌
     *
     * @param loginUser 用户信息
     * @return 令牌
     */
    public String createToken(LoginUser loginUser)
    {
        String token = IdUtils.fastUUID();
        loginUser.setToken(token);
        setUserAgent(loginUser);
        refreshToken(loginUser);

        Map<String, Object> claims = new HashMap<>();
        claims.put(Constants.LOGIN_USER_KEY, token);
        return createToken(claims);
    }
private String createToken(Map<String, Object> claims)
    {
        String token = Jwts.builder()
                .setClaims(claims)
                .signWith(SignatureAlgorithm.HS512, secret).compact();
        return token;
    }

再看一下验证token的源码。会先获取当前的系统时间,,相差不足20分钟,自动刷新缓存,通过刷新缓存的方法,会把内容刷入redis中。

    public void verifyToken(LoginUser loginUser)
    {
        long expireTime = loginUser.getExpireTime();
        long currentTime = System.currentTimeMillis();
        if (expireTime - currentTime <= MILLIS_MINUTE_TEN)
        {
            refreshToken(loginUser);
        }
    }

下一部分是验证token:

验证token是结合了SpringSecurity,使用了JwtAuthenticationTokenFilter这个过滤器来进行解析。

第一步是获取请求里面的token,从里面获取对应的用户和权限信息。

    public LoginUser getLoginUser(HttpServletRequest request)
    {
        // 获取请求携带的令牌
        String token = getToken(request);
        if (StringUtils.isNotEmpty(token))
        {
            try
            {
                Claims claims = parseToken(token);
                // 解析对应的权限以及用户信息
                String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
                String userKey = getTokenKey(uuid);
                LoginUser user = redisCache.getCacheObject(userKey);
                return user;
            }
            catch (Exception e)
            {
            }
        }
        return null;
    }

里面的一步是获取请求头里面的token

    private String getToken(HttpServletRequest request)
    {
        String token = request.getHeader(header);
        if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX))
        {
            token = token.replace(Constants.TOKEN_PREFIX, "");
        }
        return token;
    }

获取到token 之后就是解析,这里也是调用现有的库。

    private Claims parseToken(String token)
    {
        return Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();
    }

解析完之后,后面就是验证token,有效的话就会刷新时效,如果是无效的话,会在过滤器中抛出异常。

再用户退出之后,若依框架对于token的处理是对token进行删除,相关的代码在LogoutSuccessHandlerImpl.java中。

@Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
            throws IOException, ServletException
    {
        LoginUser loginUser = tokenService.getLoginUser(request);
        if (StringUtils.isNotNull(loginUser))
        {
            String userName = loginUser.getUsername();
            // 删除用户缓存记录
            tokenService.delLoginUser(loginUser.getToken());
            // 记录用户退出日志
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功"));
        }
        ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(HttpStatus.SUCCESS, "退出成功")));
    }

总结一下,这里使用了jwt作为认证的框架,jwt是否比传统的session-cookie一定适合web应用还是存在疑问的,本篇文章仅仅研究很分析了一下这个框架使用jwt的基本流程。

相关推荐

团队管理“布阵术”:3招让你的团队战斗力爆表!

为何古代军队能够以一当十?为何现代企业有的团队高效似“特种部队”,有的却松散若“游击队”?**答案正隐匿于“布阵术”之中!**今时今日,让我们从古代兵法里萃取3个核心要义,助您塑造一支战斗力爆棚的...

知情人士回应字节大模型团队架构调整

【知情人士回应字节大模型团队架构调整】财联社2月21日电,针对原谷歌DeepMind副总裁吴永辉加入字节跳动后引发的团队调整问题,知情人士回应称:吴永辉博士主要负责AI基础研究探索工作,偏基础研究;A...

豆包大模型团队开源RLHF框架,训练吞吐量最高提升20倍

强化学习(RL)对大模型复杂推理能力提升有关键作用,但其复杂的计算流程对训练和部署也带来了巨大挑战。近日,字节跳动豆包大模型团队与香港大学联合提出HybridFlow。这是一个灵活高效的RL/RL...

创业团队如何设计股权架构及分配(创业团队如何设计股权架构及分配方案)

创业团队的股权架构设计,决定了公司在随后发展中呈现出的股权布局。如果最初的股权架构就存在先天不足,公司就很难顺利、稳定地成长起来。因此,创业之初,对股权设计应慎之又慎,避免留下巨大隐患和风险。两个人如...

消息称吴永辉入职后引发字节大模型团队架构大调整

2月21日,有消息称前谷歌大佬吴永辉加入字节跳动,并担任大模型团队Seed基础研究负责人后,引发了字节跳动大模型团队架构大调整。多名原本向朱文佳汇报的算法和技术负责人开始转向吴永辉汇报。简单来说,就是...

31页组织效能提升模型,经营管理团队搭建框架与权责定位

分享职场干货,提升能力!为职场精英打造个人知识体系,升职加薪!31页组织效能提升模型如何拿到分享的源文件:请您关注本头条号,然后私信本头条号“文米”2个字,按照操作流程,专人负责发送源文件给您。...

异形柱结构(异形柱结构技术规程)

下列关于混凝土异形柱结构设计的说法,其中何项正确?(A)混凝土异形柱框架结构可用于所有非抗震和抗震设防地区的一般居住建筑。(B)抗震设防烈度为6度时,对标准设防类(丙类)采用异形柱结构的建筑可不进行地...

职场干货:金字塔原理(金字塔原理实战篇)

金字塔原理的适用范围:金字塔原理适用于所有需要构建清晰逻辑框架的文章。第一篇:表达的逻辑。如何利用金字塔原理构建基本的金字塔结构受众(包括读者、听众、观众或学员)最容易理解的顺序:先了解主要的、抽象的...

底部剪力法(底部剪力法的基本原理)

某四层钢筋混凝土框架结构,计算简图如图1所示。抗震设防类别为丙类,抗震设防烈度为8度(0.2g),Ⅱ类场地,设计地震分组为第一组,第一自振周期T1=0.55s。一至四层的楼层侧向刚度依次为:K1=1...

结构等效重力荷载代表值(等效重力荷载系数)

某五层钢筋混凝土框架结构办公楼,房屋高度25.45m。抗震设防烈度8度,设防类别丙类,设计基本地震加速度0.2g,设计地震分组第二组,场地类别为Ⅱ类,混凝土强度等级C30。该结构平面和竖向均规则。假定...

体系结构已成昭告后世善莫大焉(体系构架是什么意思)

实践先行也理论已初步完成框架结构留余后人后世子孙俗话说前人栽树后人乘凉在夏商周大明大清民国共和前人栽树下吾之辈已完成结构体系又俗话说青出于蓝而胜于蓝各个时期任务不同吾辈探索框架结构体系经历有限肯定发展...

框架柱抗震构造要求(框架柱抗震设计)

某现浇钢筋混凝土框架-剪力墙结构高层办公楼,抗震设防烈度为8度(0.2g),场地类别为Ⅱ类,抗震等级:框架二级,剪力墙一级,混凝土强度等级:框架柱及剪力墙C50,框架梁及楼板C35,纵向钢筋及箍筋均采...

梁的刚度、挠度控制(钢梁挠度过大会引起什么原因)

某办公楼为现浇钢筋混凝土框架结构,r0=1.0,混凝土强度等级C35,纵向钢筋采用HRB400,箍筋采用HPB300。其二层(中间楼层)的局部平面图和次梁L-1的计算简图如图1~3(Z)所示,其中,K...

死要面子!有钱做大玻璃窗,却没有钱做“柱和梁”,不怕房塌吗?

活久见,有钱做2层落地大玻璃窗,却没有钱做“柱子和圈梁”,这样的农村自建房,安全吗?最近刷到个魔幻施工现场,如下图,这栋5开间的农村自建房,居然做了2个全景落地窗仔细观察,这2个落地窗还是飘窗,为了追...

不是承重墙,物业也不让拆?话说装修就一定要拆墙才行么

最近发现好多朋友装修时总想拆墙“爆改”空间,别以为只要避开承重墙就能随便砸!我家楼上邻居去年装修,拆了阳台矮墙想扩客厅,结果物业直接上门叫停。后来才知道,这种配重墙拆了会让阳台承重失衡,整栋楼都可能变...

取消回复欢迎 发表评论: