若依学习笔记04——JWT

JWT是个啥

        官方是这么解释的:

        JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.

  • 官网地址: https://jwt.io/introduction/

        通俗一点解释就是一个令牌,用于各方面之间的数据传输,以JSON的形式,传输的过程中还可以进行数据加密或者签名啥的操作。

        有篇文章总结的挺好,抄一下描述:

————————————————

        JWT 默认是不加密,但也是可以加密的。生成原始 Token 以后,可以用密钥再加密一次。
        JWT 不加密的情况下,不能将秘密数据写入 JWT。
        JWT 不仅可以用于认证,也可以用于交换信息。有效使用 JWT,可以降低服务器查询数据库的次数。
        JWT的最大缺点:由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或更改 token 的权限。即,一旦 JWT 签发,在到期之前就会始终有效,除非服务器部署额外的逻辑。
        JWT 本身包含认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。
        为减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输。
————————————————
版权声明:以上这段总结为CSDN博主「johnny233」的原创文章,遵循CC 4.0 BY-SA版权协议。
原文链接:https://blog.csdn.net/lonelymanontheway/article/details/107373397

JWT的结构

        三段:JWT令牌 = Header.Payload.Signature

        1.标头(Header)

        一般有两部分:令牌的类型和所用的签名算法。这部分信息用Base64编码组成JWT结构第一部分。

        Base64是一种编码,并不是加密,是可逆的,编码后可以被翻译成原来的样子,所以内容并不安全。

        2.有效载荷(Payload)

        有效负载,包含声明。声明是有关实体和其他数据的声明(一般是用户和存放用户信息的)。也是用Base64编码组成JWT第二部分。

        3.签名(Signature)

        签名需要使用编码后的header和payload以及我们提供的一个密钥,然后使用header中指定的签名算法进行签名。签名的作用是保证JWT没有被篡改过。

        base64(header) . base64(payload) . "#**$s@8ss"(秘钥) -----> 组成 Signature
同下
        HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload),secret); -----> 组成 Signature

        由于使用的Base64编码,是可逆的编码方式,所以JWT并不安全,不应该在负载中加入任何敏感数据。JWT还经常用于设计用户认证和授权系统,甚至实现Web应用单点登录。

JWT特点

        输出三个由.分隔的Base64-URL字符串,可以在HTML和HTTP环境中轻松传递,与基于XML的标准相比,更加紧凑。

        简洁(Compact):可以通过URL,POST参数或者在HTTP header发送,数据量小,传输速度快。

        自包含(Self-contained)负载中包含了所有用户所需要的信息,避免了多次查询数据库。

JWT在若依中的应用

后端/login接口

        前端获取userName、password、code验证码 后调用接口,整体改接口做以下步骤:

        1.验证身份(账号密码验证码三位一体)

        2.生成token

        3.保存用户登录态至Spring Security

安全配置:定义了基本的配置信息
framework.config.SecurityConfig

UserDetailsServiceImpl 用户验证处理类

登录接口的服务类
framework.web.service.SysLoginService

JWT拦截器,拦截令牌并校验信息
framework.security.filter.JwtAuthenticationTokenFilter

过程:

        1.SysLoginService 中调用UserDetailsServiceImpl校验用户的密码是否匹配以及用户账户状态,校验通过后返回UserDetails实例,该实例包含了用户的基本信息和菜单权限信息。
        2.调用tokenService.createToken(loginUser)生成token。

JWT生成过程:

  1. 生成uuid随机数,这个随机数用来做rediskey存储token。
  2. 生成一个token(无时效)。
  3. 拦截到的token如果距离失效在10分钟以内(可配置)就自动刷新有效期。

过滤器进行JWT令牌校验

/**
 * token过滤器 验证token有效性
 * 
 * @author sj
 */
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
{
    @Autowired
    private TokenService tokenService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException
    {
        LoginUser loginUser = tokenService.getLoginUser(request);
        if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication()))
        {
            tokenService.verifyToken(loginUser);
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        }
        chain.doFilter(request, response);
    }
}

        过滤器拦截所有请求并对JWT进行校验和刷新,详细过程:

        1.tokenService.getLoginUser(request); 从request中获取token并校验,如果校验通过就返回LoginUser对象
        2.校验LoginUser的token,如果再刷限期内就直接刷新
        3.将LoginUser封装到SecurityContextHolder中作为全局的用户登录状态
原文链接:https://blog.csdn.net/kouryoushine/article/details/110780053

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值