JWT如何获取用户分配的角色跳转对应Dashboard?JWT不返回角色信息如何解决
问题根源
你当前的逻辑仅返回JWT令牌本身,既没有将角色信息写入JWT载荷,也没有在响应体中额外返回用户角色字段,所以前端无法获取角色做权限判断。
后端修改步骤
1. 调整JWT生成逻辑,写入角色信息
修改JwtTokenUtil类的令牌生成方法,将用户角色作为自定义声明写入JWT载荷:
// 新增带自定义声明的生成方法,原有createToken方法无需改动 public String generateToken(UserDetails userDetails, Set<UserRole> roles) { Map<String, Object> claims = new HashMap<>(); // 提取角色名称存入声明 List<String> roleList = roles.stream() .map(UserRole::getRoleName) // 替换为你UserRole类中实际的角色名字段get方法 .collect(Collectors.toList()); claims.put("roles", roleList); return createToken(claims, userDetails.getUsername()); }
2. 调整登录接口返回值
首先修改JwtResponse类,新增角色字段、对应的构造方法和getter:
public class JwtResponse { private String token; private List<String> roles; // 新增构造方法 public JwtResponse(String token, List<String> roles) { this.token = token; this.roles = roles; } // 原有getter/setter保留,新增roles的getter public List<String> getRoles() { return roles; } }
再修改UserController的/validate接口:
@PostMapping(value="/validate") public ResponseEntity<?> createAuthenticationToken(@RequestBody MyUserDetails authenticationRequest) throws Exception { authenticate(authenticationRequest.getUsername(), authenticationRequest.getPassword()); // 新增查询完整用户实体的逻辑,需要在UserAccountService中加findByUsername方法 User user = userAccountService.findByUsername(authenticationRequest.getUsername()); final UserDetails userDetails = userAccountService.loadUserByUsername(authenticationRequest.getUsername()); // 生成带角色的令牌 final String token = jwtTokenUtil.generateToken(userDetails, user.getUserRole()); List<String> roleList = user.getUserRole().stream() .map(UserRole::getRoleName) .collect(Collectors.toList()); // 返回带角色的响应 return ResponseEntity.ok(new JwtResponse(token, roleList)); }
3. (可选)后端接口加权限校验
所有管理员专属接口添加权限注解,避免越权调用:
@PreAuthorize("hasRole('ADMIN')") @GetMapping("/list/User/") public List<User> getUserList() { // 原有逻辑 }
前端修改步骤
1. 登录逻辑增加权限判断
修改身份验证类的登录回调,存储角色并做跳转判断:
axios.post(baseURL,data) .then(res =>{ localStorage.setItem('token', res.data.token) // 存储角色到本地 localStorage.setItem('roles', JSON.stringify(res.data.roles)) // 校验是否为管理员 const roleList = JSON.parse(localStorage.getItem('roles') || '[]') if(roleList.includes('ADMIN')) { this.props.history.push('/admin/index') } else { // 普通用户跳转对应页面,或提示无权限 alert('无管理员权限') this.props.history.push('/login') } })
2. 管理员页面加路由守卫
修改Admin.js,进入页面前先校验权限:
React.useEffect(() => { // 先做权限校验 const roleList = JSON.parse(localStorage.getItem('roles') || '[]') if(!roleList.includes('ADMIN') || !localStorage.getItem('token')) { window.location.href = '/login' return } // 原有请求逻辑保留 const config = { headers:{ Authorization: 'Bearer ' + localStorage.getItem('token') } } axios.get('http://localhost:8080/list/User/',config).then( res => { console.log(res.data) }, err => { console.log(err) } ) // 原有滚动逻辑保留 }, [location]);
内容的提问来源于stack exchange,提问作者wizdemonizer
相关产品推荐
相关产品推荐

