基于Interceptor+JWT+Redis的后端API权限验证小实现

本文介绍了一个小型前后端项目中的权限认证实现,采用RBAC模型,使用JWT进行鉴权,通过Interceptor处理API权限。登录逻辑包括用户信息存储到Redis中,登录失败和成功的处理。项目中还涉及自定义异常处理和拦截器,拦截器负责验证token并根据用户权限决定是否允许访问特定接口。文章讨论了手动维护接口权限和角色映射的不便,以及Token有效期带来的问题。

前言

  • 本章节是做一个小型的前后端项目的验证授权控制简单Demo实现方案
  • 重点在于后端API的权限认证
  • 这种实现方式比较low,不容易开发维护,此博客还写的很丑陋,建议自己看项目代码分析就好(重点在于Interceptor的逻辑),很快就明白的。
  • 项目地址:github.com/Tonciy/perm…

1. 描述

1.1 实现思路

  • 总体流程如下:

  • 登录逻辑如下:

  • 请求权限认证如下

1.2 用户访问API划分

  • 如下图所示

2. 环境搭建

2.1 数据库

  • 基于RBAC模型建立的,比较简单

  • 在这里要特别描述下权限表的各个字段含义:

    • 比如做SaaS如果还要细分的话,权限表实际上还可以拆,这里只是一个权限认证的小Demo,就简单化了
  • 本Demo中权限表中的具体数据如下图所示(特别注意每行记录中的api_identify值,代表某个接口的唯一标识符,后面在Controller中会有对应标明")

2.2 项目

  • 项目地址:github.com/Tonciy/perm…

  • 由于总体上比较简单,这里只描述一些重要的点,其余的自行查看发布到GitHub的项目

    1. 登录接口

      @RestController
      @RequestMapping("/login")
      public class LoginController {
          @Resource
          private UserService userService;
      ​
          @Resource
          private JwtUtils jwtUtils;
      ​
          @Resource
          private RedisTemplate<String, Object> redisTemplate;
      ​
          @Value("${redis.user.prefix}")
          private String redisKeyPrefix;
      ​
          @Value("${jwt.config.ttl}")
          private Long time = 1800L;
      ​
          @PostMapping
          public Result login(String username,  String password) throws CommonException {
              if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)){
                  throw new CommonException(ResultCode.REQUEST_PARARMETER_MISS);
              }
              User user = userService.findByUsername(username);
              if(user == null){
                  // 不存在此用户,登录失败
                  return new Result(ResultCode.USERNAME_PASSWORD_ERROR);
              }else{
                  // 比对密码
                  if(password.equals(user.getPassword())){
                      // 登录成功,存储当前用户到Redis里(设置存活时间) 签发token
                      redisTemplate.opsForValue().set(redisKeyPrefix + user.getId(), user, time, TimeUnit.SECONDS);
                      String token = jwtUtils.createJwt(user.getId(), user.getUsername(), null);
                      return Result.SUCCESS(token);
                  }else{
                      // 密码错误
                      return new Result(ResultCode.USERNAME_PASSWORD_ERROR);
                  }
              }
          }
      }
      复制代码
      • 这里的登录逻辑是按照上述的逻辑图来实现的
      • 特别注意用户信息存放到Redis中的key,是通过配置的前缀 + 用户id拼接成的
      • 有效时间也是通过配置来设置的,否则有个默认时间
    2. 两个Controller注意每个接口上的请求映射注解name属性上,都标明了此接口对应的唯一标识符

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值