系统多种用户角色认证登录授权如何实现?

前提:本项目是springboot写的后端,使用spring security + jwt实现去实现student、company、admin三种用户角色的认证与授权

方法1:建立全局唯一的用户标识符uuid

为每个用户生成一个全局的UUID。

前情提要:本来设计了三张数据库表:student、company、admin。每张表存放相应角色相应用户的基本信息(id,username,password,email等信息,每种用户信息需要的字段大为不同,所以设计了三张表)

具体操作:创建一个同一用户表user,用来存放所有用户共有信息(username,password),这张总表有一个字段为uuid,是每个用户全局唯一的id。然后在具体的student、company、admin表中引用这个全局id,并且存放各自特有的信息。

方法2:在jwt中包含用户类型

在JWT的claims中明确包含用户类型,这样即使id重复了,可以通过用户类型来判断用户是属于哪个表。通过修改jwt生成和解析逻辑来实现

修改jwt生成逻辑

在生成jwt时,除了用户id外,还要包含用户类型
backend/utils/JwtUtil.java:

...
// 调用getJwtBuilder方法创建一个新的jwt
    public static String createJWT(String userId,String userType) {
        // 这里应该将用户id和用户类型拼接成一个字符串为subject
        String subject = userId + ',' + userType;
        JwtBuilder builder = getJwtBuilder(subject, null, getUUID()); // 构建jwt
        return builder.compact(); // 返回一个压缩过的jwt
    }
...

修改解析jwt逻辑

backend/config/filter/JwtAuthenticationTokenFilter.java

...
// 截取实际的jwt部分,处理验证jwt
        token = token.substring(7);
        String userId;
        String userType;
        try {
            Claims claims = JwtUtil.parseJWT(token); // 尝试解析
            // 解析成功后,claims.getSubject()返回的是一个字符串,包含两部分"userId,userType"
            String[] = claims.getSubject().split(",");
            userId = parts[0];
            userType = parts[1];
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
...

接下来就要去调整数据库查询逻辑,将查到的user实体及其usertype提取到spring security上下文中

调整数据库查询逻辑

当从数据库中查询用户信息时,总是同时考虑用户ID和用户类型。例如,在Spring服务中,可以为每种用户类型提供不同的查询方法,或者创建一个更通用的查询方法,它接受用户ID和用户类型作为参数。

具体措施有待更新...

前端和后端的验证

在前端和后端都进行用户类型的验证,确保在执行任何用户相关的操作时都考虑到用户类型。例如,不应该允许一个以company身份认证的用户ID去访问admin特有的接口。

具体措施有待更新...
posted @ 2024-04-06 12:10  r涤生  阅读(98)  评论(0编辑  收藏  举报