Generating and Revoking API Tokens¶
API tokens are used to authenticate requests to the REST API. The application uses a secure token system where tokens are generated per user, have a defined expiration time, and can be revoked. The core logic is handled by methods within the User model in app/models.py.
Token Generation¶
Tokens are generated using the get_token() method. A token is automatically created or refreshed upon user registration, login, or when an existing token is close to expiring.
Method Definition¶
Defines the method for generating a token, with a default expiration of 1 hour (3600 seconds).
def get_token(self, expires_in=3600):
Existing Token Check¶
Returns the existing token if it is still valid for more than 60 seconds, avoiding unnecessary regeneration.
now = datetime.now(timezone.utc)
if self.token and self.token_expiration and \
self.token_expiration.replace(tzinfo=timezone.utc) > now + timedelta(seconds=60):
return self.token
New Token Creation¶
Generates a new, cryptographically secure 32-character hexadecimal token.
self.token = secrets.token_hex(16)
Set Expiration¶
Sets the expiration timestamp for the new token.
self.token_expiration = now + timedelta(seconds=expires_in)
Token Revocation¶
Revoking a token invalidates it immediately. This is handled by the revoke_token() method.
Method Definition¶
Defines the method for revoking a user’s current API token.
def revoke_token(self):
Invalidate Expiration¶
Sets the token’s expiration date to a time in the past, effectively invalidating it.
self.token_expiration = datetime.now(timezone.utc) - timedelta(seconds=1)
Token Verification and Auto-Renewal¶
API routes are protected using a token verification mechanism. The static method User.check_token() is used to validate incoming tokens.
Method Definition¶
Defines the static method that checks the validity of a given token.
@staticmethod
def check_token(token):
User Lookup¶
Finds the user associated with the provided token.
user = db.session.scalar(sa.select(User).where(User.token == token))
Expiration Check¶
Returns None if the user does not exist or if the token has expired.
if user is None or user.token_expiration.replace(tzinfo=timezone.utc) < datetime.now(timezone.utc):
return None
Auto-Renewal Logic¶
If the token is valid but has less than 60 seconds remaining, a new token is automatically generated and saved, ensuring seamless API access for active users.
if user.token_expiration.replace(tzinfo=timezone.utc) < datetime.now(timezone.utc) + timedelta(seconds=60):
user.get_token()
db.session.commit()
return user