前提:本项目是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特有的接口。
具体措施有待更新...
标签:...,String,登录,userId,jwt,用户,认证,授权,id
From: https://www.cnblogs.com/rdisheng/p/18117302