Symfony 3.3.10中LexikJWT令牌生成字段调整及身份字段变更报错问题
Hey there, let's sort out this problem you're facing. First, let's clear up a key misunderstanding: JWT tokens are stateless and NOT stored in server-side sessions. When you generate a token with the user's email as the identity field, that email gets encoded directly into the token. Once the token is issued, it doesn't automatically update when the user's email changes in the database—so when you try to use the old token, the encoded email doesn't match the new one in your DB, hence the error.
Here are the most practical solutions to adjust your token logic:
1. Generate a New Token Immediately After Email Update
The simplest and most secure approach is to issue a fresh JWT token right after the user successfully updates their email. This way, the front-end can replace the old token with the new one, and all subsequent requests will use the updated identity.
In your controller handling the PUT request for email updates, add code to generate the new token:
// After saving the updated user to the database $jwtManager = $this->get('lexik_jwt_authentication.jwt_manager'); $newToken = $jwtManager->create($user); // Return the new token to the front-end (e.g., in a JSON response) return new JsonResponse([ 'message' => 'Email updated successfully', 'token' => $newToken ]);
Make sure your front-end replaces the stored token with this new one immediately.
2. Switch to a Stable Identity Field (Like User ID)
If you want to avoid token invalidation when changing user emails, you can change the user_identity_field from email to id (since a user's ID should never change). This way, the token is tied to the user's immutable ID instead of their mutable email.
Update your config.yml (or relevant config file) for LexikJWTBundle:
lexik_jwt_authentication: # ... other configs user_identity_field: id
Note: You can still let users log in with their email—this change only affects what data is used to generate and validate the token. The bundle will still find the user by ID during authentication, which remains consistent even if the email changes.
3. Implement a Token Blacklist (For Enhanced Security)
If you need to invalidate the old token immediately (to prevent any leftover uses of the outdated token), you can add a token blacklist system. LexikJWTBundle doesn't include this out of the box, but you can build it easily:
- Create a database table or use a cache (like Redis) to store revoked tokens, along with their expiration times.
- Listen to the
lexik_jwt_authentication.on_jwt_authenticatedevent to check if the incoming token is in the blacklist. If it is, throw an authentication exception. - When the user updates their email, add the old token to the blacklist.
Example event listener snippet:
use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTAuthenticatedEvent; use Symfony\Component\Security\Core\Exception\BadCredentialsException; class TokenBlacklistListener { private $blacklistRepository; public function __construct(BlacklistRepository $blacklistRepository) { $this->blacklistRepository = $blacklistRepository; } public function onJWTAuthenticated(JWTAuthenticatedEvent $event) { $token = $event->getToken(); if ($this->blacklistRepository->isTokenRevoked($token)) { throw new BadCredentialsException('This token has been revoked.'); } } }
Remember: JWT's strength is its statelessness, but that means you have to handle identity changes explicitly. The first two solutions are the most straightforward for your use case.
内容的提问来源于stack exchange,提问作者shuba.ivan

