Grails REST Security:为/api/login返回的Token添加用户ID字段
Got it, let's fix this to add the id field to your /api/login response. Based on the response structure you shared, it looks like you're working with JWT tokens (probably in a Spring Boot/Spring Security setup, given the format). Here are the most common approaches to get this done:
1. Custom Login Response DTO (Simplest for Custom Login Endpoints)
If you're handling login with a custom controller endpoint, the easiest way is to define a response DTO that includes the id field, then populate it when building your response.
Step 1: Define the Response DTO
public class LoginResponse { private String id; private String username; private List<String> roles; private String token_type; private String access_token; private Long expires_in; private String refresh_token; // Constructor, getters, and setters for all fields }
Step 2: Populate the DTO in Your Login Controller
When generating the response after successful authentication, fetch the user ID from your authenticated user details and add it to the DTO:
@PostMapping("/api/login") public ResponseEntity<LoginResponse> login(@RequestBody LoginRequest loginRequest) { // Authenticate the user (standard Spring Security logic) Authentication authentication = authenticationManager.authenticate( new UsernamePasswordAuthenticationToken( loginRequest.getUsername(), loginRequest.getPassword() ) ); SecurityContextHolder.getContext().setAuthentication(authentication); // Get the authenticated user details (assume you have a custom UserDetails implementation) CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal(); // Generate your JWT tokens (use your existing token generation logic here) String accessToken = jwtTokenProvider.generateToken(userDetails); String refreshToken = jwtTokenProvider.generateRefreshToken(userDetails); // Build the response with the user ID LoginResponse response = new LoginResponse(); response.setId(userDetails.getId()); // Add the user ID here response.setUsername(userDetails.getUsername()); response.setRoles(userDetails.getAuthorities().stream() .map(GrantedAuthority::getAuthority) .collect(Collectors.toList())); response.setToken_type("Bearer"); response.setAccess_token(accessToken); response.setExpires_in(3600L); response.setRefresh_token(refreshToken); return ResponseEntity.ok(response); }
2. Use TokenEnhancer (For Spring Security OAuth2 Setups)
If you're using Spring Security OAuth2 to handle token issuance, you can create a custom TokenEnhancer to inject the user ID into the token response.
Step 1: Create the Custom TokenEnhancer
@Component public class CustomTokenEnhancer implements TokenEnhancer { @Override public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { Map<String, Object> additionalInfo = new HashMap<>(); // Fetch the user ID from the authenticated principal User user = (User) authentication.getPrincipal(); // Replace with your user entity class additionalInfo.put("id", user.getId()); ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo); return accessToken; } }
Step 2: Configure the Token Enhancer in Authorization Server
Wire up the enhancer in your authorization server configuration to include it in the token generation chain:
@Configuration @EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private CustomTokenEnhancer customTokenEnhancer; @Autowired private JwtAccessTokenConverter jwtAccessTokenConverter; @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain(); tokenEnhancerChain.setTokenEnhancers(Arrays.asList(customTokenEnhancer, jwtAccessTokenConverter)); endpoints.tokenEnhancer(tokenEnhancerChain); // Add other necessary configurations (user details service, authentication manager, etc.) } }
Key Notes
- Make sure your
UserDetailsimplementation (or user entity) exposes theidfield with a getter method. - If you're using a different framework (like Node.js, Python Flask/Django), the core idea stays the same: fetch the authenticated user's ID after login, then add it to your response payload before sending it back.
内容的提问来源于stack exchange,提问作者ziftech

