generateTokens method
Generates tokens for a user
user The user to generate tokens for
Returns authentication response with tokens
Implementation
@override
Future<AuthResponse> generateTokens(Authenticatable user) async {
final now = DateTime.now();
final userId = user.getAuthIdentifier();
// Generate a unique session/correlation ID to link access and refresh tokens
final sessionId = _tokenGenerator.generateToken(length: 32);
// Create JWT payload - ensure 'sub' is always a string
final payload = {
'sub': userId,
'iat': now.millisecondsSinceEpoch ~/ 1000,
'exp': now.add(_accessTokenExpiry).millisecondsSinceEpoch ~/ 1000,
'jti': sessionId, // Use standard JWT ID claim for session correlation
'user': _sanitizeUserData(user.toAuthArray()),
};
// Generate JWT
final jwt = JWT(payload);
final accessToken = jwt.sign(SecretKey(_secret));
// Generate refresh token with embedded session ID
// Format: <session_id>::<token> to enable correlation without schema changes
final rawRefreshToken = _tokenGenerator.generateToken();
final refreshToken = '$sessionId::$rawRefreshToken';
// Store refresh token in database using injected service
final refreshTokenData = {
'token': refreshToken, // Contains session correlation in token format
'tokenable_id': userId,
'guard': _providerKey,
'type': 'refresh',
'created_at': DateTime.now().toIso8601String(),
'expires_at': DateTime.now().add(_refreshTokenExpiry).toIso8601String(),
};
await _tokenService.storeToken(refreshTokenData);
return AuthResponse(
user: user.toAuthArray(),
accessToken: accessToken,
refreshToken: refreshToken,
expiresIn: _accessTokenExpiry.inSeconds,
refreshExpiresIn: _refreshTokenExpiry.inSeconds,
);
}