面试题答案
一键面试JWT Payload设计
- 通用信息:
sub
(subject):标识用户的唯一标识符,例如用户ID。role
:用户角色,取值为admin
(管理员)、user
(普通用户)、guest
(访客)。
- 普通用户额外信息(针对不同小组权限):
- 当
role
为user
时,添加group
字段,标识用户所属小组。例如group: "group1"
。 - 同时添加
permissions
字段,以数组形式列出该用户或小组所拥有的具体权限。例如["read_file", "write_file"]
。
- 当
- 示例Payload:
对于管理员,可以简化为:{ "sub": "1234567890", "role": "user", "group": "group1", "permissions": ["read_file", "write_file"] }
对于访客:{ "sub": "0987654321", "role": "admin", "permissions": ["all_permissions"] }
{ "sub": "guest_id_1", "role": "guest", "permissions": ["view_public_content"] }
服务端权限验证
- 验证JWT合法性:
- 使用JWT库验证JWT的签名,确保JWT未被篡改。例如在Java中可以使用
jjwt
库:
try { Claims claims = Jwts.parserBuilder() .setSigningKey(secretKey) .build() .parseClaimsJws(jwt) .getBody(); } catch (JwtException e) { // JWT不合法,返回权限不足等错误 return false; }
- 使用JWT库验证JWT的签名,确保JWT未被篡改。例如在Java中可以使用
- 基于角色和权限的验证:
- 从解析后的Payload中获取
role
字段。 - 如果
role
为admin
,则赋予所有权限,直接通过验证。 - 如果
role
为user
,获取group
和permissions
字段。根据请求的操作,检查permissions
数组中是否包含对应的权限。例如,请求写文件操作,检查permissions
数组中是否有write_file
权限。 - 如果
role
为guest
,同样根据请求操作检查permissions
数组,判断是否具有相应权限。
- 从解析后的Payload中获取
- 缓存优化:
- 对于频繁访问且权限相对固定的资源,可以将权限验证结果进行缓存。例如使用Redis缓存,以用户ID和资源路径作为键,权限验证结果作为值。在每次权限验证时,先检查缓存中是否已有结果,若有则直接返回,提高验证效率。