文章

【若依】13、登录、授权流程梳理

登录流程梳理

登录请求

  1. 登录请求,直接发送给登录接口/login,具体的处理方法位于top.yueyazhui.tienchin.web.controller.system.SysLoginController#login
    1. 调用authenticationManager.authenticate方法执行登录操作。这个登录操作,最终会调用到 top.yueyazhui.tienchin.framework.web.service.UserDetailsServiceImpl#loadUserByUsername方法进行用户登录的认证,认证成功之后会返回一个 LoginUser,这个 LoginUser 中包含用户的基本信息,包括根据用户 id 从数据库中查询到的用户权限。
    2. 接下来创建登录令牌,所谓的另外,实际上是一个 JWT 字符串,具体的生成过程如下:
      1. 先获取一个经过处理的 UUID。
      2. 以 uuid 为 key,登录成功的用户 LoginUser 为 value,将之存储到 Redis 中。
      3. 生成一个 JWT 字符串,这个 JWT 字符串的内容就只有第一步获取到的 UUID。

        其他请求

        以后所有的登录之外的请求,只要需要认证,都会经过top.yueyazhui.tienchin.framework.security.filter.JwtAuthenticationTokenFilter类,这个类核心功能就是根据用户登录时候的 JWT 字符串,去 Redis 中查询到登录用户对象,并存入到 SecurityContextHolder 中。

  2. 以后其他请求来的时候,必须携带上 JWT 字符串,携带方式就是将 JWT 字符串放入到请求头中,不携带的话,就认证不通过。
  3. JwtAuthenticationTokenFilter过滤器中,会直接进行 JWT 字符串的处理,根据 JWT 字符串解析出当前登录的用户,具体的处理逻辑在top.yueyazhui.tienchin.framework.web.service.TokenService#getLoginUser方法中:
    1. 先从请求头中提取出 JWT 字符串。
    2. 使用 JWT 解析这个 JWT 字符串。
    3. 根据解析后的 JWT 字符串,再提取出 JWT 中的 token,然后根据这个 token 去 redis 中查询到当前登录的用户对象。
    4. 用于用户对象存储在 Redis 中,有过期时间,这里拿到之后,刷新一下当前用户在 Redis 中的过期时间。
    5. 最后,将当前登录用户对象存入到 SecurityContextHolder 中。

      鉴权流程梳理

  4. 当用户登录成功的时候,就已经把用户的权限信息保存到 LoginUser 中了,当每次请求到达的时候,都会在JwtAuthenticationTokenFilter过滤器中,重新获取到用户的基本信息(包括用户的权限)存入到 SecurityContextHolder 中。
  5. 以后,用户访问某一个接口,或者某一个方法的时候,我们需要进行权限控制的时候,直接通过@PreAuthorize("hasPermission('system:dict:export')")注解去执行即可,这个注解中,会获取到当前用户的角色信息,并和需要的角色信息进行比对。
本文由作者按照 CC BY 4.0 进行授权