Authentication

The UContact REST API Service uses JWT (JSON Web Token) based authentication with email verification.

Authentication Flow

  1. Registration: Users register with email, username, and password

  2. Email Verification: A verification link is sent to the user’s email

  3. Login: Users login with username/password to receive JWT tokens

  4. API Access: Protected endpoints are accessed using the JWT token

  5. Token Refresh: Expired tokens can be refreshed using a refresh token

API Endpoints

Register

Register a new user with email verification.

Request Body:

{
    "username": "johndoe",
    "email": "john@example.com",
    "password": "securepassword123"
}

Response:

{
    "id": 1,
    "username": "johndoe",
    "email": "john@example.com",
    "created_at": "2025-04-16T12:00:00",
    "avatar": null,
    "is_verified": false
}

Login

Authenticate user and receive JWT tokens.

Request Body (form-data):

  • username: User’s username

  • password: User’s password

Response:

{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
    "refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
    "token_type": "bearer"
}

Refresh Token

Generate new JWT tokens using a refresh token.

Request Body:

{
    "refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGc..."
}

Response:

{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
    "refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
    "token_type": "bearer"
}

Email Verification

Verify user’s email address using the verification token sent via email.

Response:

{
    "message": "Email verified successfully"
}

API Implementation

Authentication Router

Authentication Service

Authentication service module for handling password hashing and JWT token operations.

This module provides services for: - Password hashing and verification using bcrypt - JWT token generation and validation for authentication - Email verification token handling - User authentication and token refresh operations

class src.services.auth.AuthService(db: sqlalchemy.ext.asyncio.AsyncSession)

Bases: TokenService

Authentication service handling user authentication and token management.

async generate_jwt(username: str) dict

Generate new access and refresh tokens for a user.

Args:

username (str): Username to generate tokens for

Returns:

dict: Dictionary containing access_token, refresh_token, and token_type

async update_jwt(username: str, refresh_token: str) dict

Update access token using existing refresh token.

Args:

username (str): Username to update token for refresh_token (str): Existing valid refresh token

Returns:

dict: Dictionary containing new access_token, existing refresh_token, and token_type

async verify_refresh_token(refresh_token: str) User | None

Verify a refresh token and return associated user.

Args:

refresh_token (str): JWT refresh token to verify

Returns:

User | None: User if token is valid and matches stored token, None otherwise

class src.services.auth.Hash

Bases: object

Password hashing service using bcrypt.

get_password_hash(password: str) str

Generate a password hash.

Args:

password (str): Plain text password to hash

Returns:

str: Bcrypt hash of the password

verify_password(plain_password, hashed_password) bool

Verify a password against its hash.

Args:

plain_password: The plain text password to verify hashed_password: The hashed password to verify against

Returns:

bool: True if password matches, False otherwise

class src.services.auth.SolveBugBcryptWarning(__version__: str = bcrypt.__version__)

Bases: object

Temporary fix for bcrypt warning issue #684.

See: https://github.com/pyca/bcrypt/issues/684

class src.services.auth.TokenService

Bases: object

Service for JWT token operations including creation and validation.

async create_access_token(data: dict, expires_delta: float | None = None) str

Create a JWT access token.

Args:

data (dict): Payload data for the token expires_delta (Optional[float], optional): Custom expiration time in seconds

Returns:

str: Encoded JWT access token

create_email_token(data: dict) str

Create a JWT token for email verification.

Args:

data (dict): Email data to encode in token

Returns:

str: Encoded JWT token valid for 7 days

async create_refresh_token(data: dict, expires_delta: float | None = None) str

Create a JWT refresh token.

Args:

data (dict): Payload data for the token expires_delta (Optional[float], optional): Custom expiration time in seconds

Returns:

str: Encoded JWT refresh token

create_reset_password_token(data: dict) str

Create a JWT token for reset password verification.

Args:

data (dict): Email data to encode in token

Returns:

str: Encoded JWT token valid for 15 minutes

create_token(data: dict, expires_delta: timedelta, token_type: Literal['access', 'refresh']) str

Create a JWT token with specified type and expiration.

Args:

data (dict): Payload data for the token expires_delta (timedelta): Token expiration time token_type (Literal[“access”, “refresh”]): Type of token to create

Returns:

str: Encoded JWT token

async get_email_from_token(token: str) str | None

Extract email from a verification token.

Args:

token (str): JWT token containing email

Returns:

str | None: Email if token is valid, None otherwise

Using Authentication

To use authentication in your requests:

  1. Register a new user account

  2. Verify your email using the link sent to your email

  3. Login to get JWT tokens

  4. Include the access token in the Authorization header:

curl -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGc..." http://localhost:8000/api/contacts

Token Expiration

  • Access tokens expire after 15 minutes (by default)

  • Refresh tokens expire after 7 days (by default)

  • Use the refresh token endpoint to get new tokens before expiration