4.项目中的用户登录检验和用户鉴权

  用户登录检验和用户鉴权是用户管理模块中重要的一环,我在网上找了一些用户登录鉴权的方法,但大多数都是通过SpringSecurity框架实现该功能。我最初也没想过使用该框架,因此自己设计了一个简便的用户登录检验以及用户鉴权模块。

1.用户登录检验

  对于用户登录检验功能,我是通过拦截器和token实现该功能。具体而言,我在登录的过程中通过登录的用户名生成token,然后将生成的token存储在request的session中。后面在拦截器中拦截请求获取token,如果token为空,表示未登录,否则登录成功。

JWT生成token的工具类

复制代码
public class JwtUtils {
    public static String createToken(String loginName){
        return Jwts.builder().
                setIssuer(CommonConstants.ISS).
                setSubject(loginName).
                setIssuedAt(new Date()).
                setExpiration(new Date(System.currentTimeMillis() + CommonConstants.EXPIRATION))
                .signWith(SignatureAlgorithm.HS512, CommonConstants.SECRET)
                .compact();
    }

    public static Date getExpiration(String token){
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(CommonConstants.SECRET).parseClaimsJws(token);
        Claims claims = claimsJws.getBody();
        Date expiredTime = claims.getExpiration();
        return expiredTime;

    }

    public static String getTokenBody(String token){
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(CommonConstants.SECRET).parseClaimsJws(token);
        Claims claims = claimsJws.getBody();
        String subject = claims.getSubject();
        return subject;

    }

    public static void main(String[] args) {
        String token = createToken("xiaoku");
        Date expiration = getExpiration(token);
        System.out.println(expiration);
    }
}
JWT工具类
复制代码

登录拦截器

复制代码
//使用拦截器简化之前的用户登录检验
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String tokenHeader = null;
        try {
            tokenHeader = request.getSession().getAttribute(CommonConstants.TOKEN_HEADER).toString();
        } catch (Exception e) {
            if (tokenHeader == null){
                return false;
            }
            e.printStackTrace();
        }

        if(!StringUtils.isEmpty(tokenHeader) && tokenHeader.startsWith(CommonConstants.TOKEN_PREFIX)){
            //处理token把开头的 "Bearer "去掉才能解析
            String token = tokenHeader.replace(CommonConstants.TOKEN_PREFIX,"").trim();
            if (token != null){
                return true;
            }
            return false;
        }
        return false;
    }
}
登录拦截器
复制代码
复制代码
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/user-info/register", "/user-info/login");
    }
}
配置类
复制代码

2.用户鉴权

  对于用户鉴权功能,我是通过token来控制用户访问接口的权限。具体而言,我自定义一个用户鉴权工具类,通过获取用户登录信息调用角色和menu相关API来匹配用户请求路径。如果用户请求路径包含用户所拥有的角色菜单路径则通过,反之无权限。

2.1 获取用户登录信息工具类

复制代码
public class SystemThreadLocal {

        //存储当前登录用户信息
        private static final Map<String, UserInfo>userInfoMap = new ConcurrentHashMap();

        public static void setUserInfo(UserInfo userInfo){
            userInfoMap.put("userInfo", userInfo);
        }

        public static UserInfo getUserInfo(){
            return userInfoMap.get("userInfo");
        }

        public static void removeUserInfo(){
            userInfoMap.remove("userInfo");
        }
}
用户登录信息工具类
复制代码

2.2 用户鉴权工具类

复制代码
//如何设计一个通用的用户鉴权呢
public class AuthUtils {

    private static Logger log = LoggerFactory.getLogger(AuthUtils.class);

    public static boolean checkAuth(HttpServletRequest request, RoleMenuMapper roleMenuMapper){


        //1.获取用户信息
        UserInfo userInfo = SystemThreadLocal.getUserInfo();
        //2..截取请求路径与权限值比较吗
        //request.getRequestURI()获取的是端口号后面的路径
        String requestUrl = request.getRequestURI().replaceFirst("/[^/]*", "");

        //3.获取数据库中该用户角色的menu路径
        List<RoleMenu> roleMenuList = roleMenuMapper.selectList(new LambdaQueryWrapper<RoleMenu>().eq(RoleMenu::getRoleId, null==userInfo?null:userInfo.getRoleId()));
        List<Integer> menuIds = roleMenuList.stream().map(x -> x.getMenuId()).collect(Collectors.toList());
        for (Integer menuId : menuIds) {
            String path = roleMenuMapper.getPath(menuId);
            log.info(path);
            if (requestUrl.contains(path)){
                return true;
            }
        }
        return false;
    }

}
用户鉴权工具类
复制代码

3.小结

  以上是我做的单体项目中简要的用户登录检验和用户鉴权功能,后面会继续学习框架中的用户登录检验和用户鉴权功能,持续更新。

 

posted @   求知律己  阅读(61)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示