generateTokens method

  1. @override
Future<AuthResponse> generateTokens(
  1. Authenticatable user
)
override

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,
  );
}