You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot后端向Angular前端传递已认证用户ID的实现疑问

嘿,折腾了4天确实闹心,不过你问的用TokenEnhancer传递用户ID完全可行,这也是JWT场景下的常规操作,我给你详细讲怎么实现,再给你几个备选方案,帮你解决问题!

方案一:用TokenEnhancer在JWT中嵌入用户ID

这是最直接的方式——把用户ID放到JWT的Payload里,前端拿到Token后解码就能获取,步骤如下:

  1. 自定义TokenEnhancer类
    这个类负责把用户ID添加到JWT的附加信息中:

    public class CustomTokenEnhancer implements TokenEnhancer {
        @Override
        public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
            // 从Authentication中获取当前认证的用户信息,这里假设你的用户类实现了UserDetails
            YourUserEntity user = (YourUserEntity) authentication.getPrincipal();
            Map<String, Object> additionalInfo = new HashMap<>();
            // 把用户ID存入附加信息,替换成你实际获取用户ID的方法
            additionalInfo.put("userId", user.getId());
            
            ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
            return accessToken;
        }
    }
    
  2. 配置到AuthorizationServer
    你需要把自定义的TokenEnhancer和JWT转换器组合成链,配置到授权服务中:

    @Configuration
    @EnableAuthorizationServer
    public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
        
        @Autowired
        private AuthenticationManager authenticationManager;
        
        @Autowired
        private TokenStore tokenStore;
    
        // 注册自定义TokenEnhancer
        @Bean
        public TokenEnhancer customTokenEnhancer() {
            return new CustomTokenEnhancer();
        }
    
        // JWT转换器,设置签名密钥
        @Bean
        public JwtAccessTokenConverter jwtAccessTokenConverter() {
            JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
            converter.setSigningKey("your-strong-secret-key"); // 替换成你的签名密钥,生产环境要用更安全的方式存储
            return converter;
        }
    
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            // 组合TokenEnhancer和JWT转换器
            TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
            tokenEnhancerChain.setTokenEnhancers(Arrays.asList(customTokenEnhancer(), jwtAccessTokenConverter()));
            
            endpoints.tokenStore(tokenStore)
                    .authenticationManager(authenticationManager)
                    .tokenEnhancer(tokenEnhancerChain);
        }
    }
    
  3. Angular前端获取用户ID
    前端拿到JWT后,解码Payload就能拿到userId。可以用jwt-decode库简化操作,或者自己手动解码:

    // 用jwt-decode的示例
    import jwtDecode from 'jwt-decode';
    
    const accessToken = localStorage.getItem('access_token');
    if (accessToken) {
        const decodedToken: any = jwtDecode(accessToken);
        const userId = decodedToken.userId;
        // 把userId存到服务或状态管理中使用
    }
    
方案二:认证成功后提供用户信息接口

如果不想修改JWT结构,也可以在用户登录成功后,让前端调用一个专门的接口获取用户ID:

  1. 后端编写用户信息接口
    这个接口需要从当前认证上下文获取用户信息:

    @RestController
    @RequestMapping("/api/auth")
    public class AuthController {
        
        @GetMapping("/user-info")
        public ResponseEntity<UserInfoResponse> getUserInfo(Authentication authentication) {
            YourUserEntity user = (YourUserEntity) authentication.getPrincipal();
            UserInfoResponse response = new UserInfoResponse();
            response.setUserId(user.getId());
            response.setUsername(user.getUsername());
            // 还可以返回其他需要的用户信息
            return ResponseEntity.ok(response);
        }
    }
    

    记得在SecurityConfig里放行这个接口(或者确保认证后能访问):

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/api/auth/user-info").authenticated()
                // 其他配置...
    }
    
  2. Angular前端调用接口
    登录成功拿到Token后,携带Token调用这个接口:

    import { HttpClient } from '@angular/common/http';
    import { Injectable } from '@angular/core';
    
    @Injectable({ providedIn: 'root' })
    export class AuthService {
        constructor(private http: HttpClient) {}
    
        getUserInfo() {
            const token = localStorage.getItem('access_token');
            return this.http.get('/api/auth/user-info', {
                headers: { 'Authorization': `Bearer ${token}` }
            });
        }
    }
    
一些注意事项
  • 确保你的用户实体类正确实现了UserDetails,或者能从Authentication.getPrincipal()中正确获取到用户ID
  • JWT的Payload是Base64编码可解码的,不要在里面存放敏感信息,用户ID这类非敏感信息完全没问题
  • 如果你用的是Spring Security 5.7及以上版本,WebSecurityConfigurerAdapter已经被标记为Deprecated,但你当前使用它的话,上面的配置完全兼容

内容的提问来源于stack exchange,提问作者dEs12ZER

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:39:27