How to Use the API – Authentication Flow (/auth)

This section explains how to obtain and use JWT tokens for securing protected endpoints. You’ll learn about the core components, request flow, and examples for obtaining and applying tokens.

Purpose and Context

  • Secure CRUD endpoints with JSON Web Tokens (JWT).
  • Leverage Flask-JWT for authentication.
  • Enforce authorization on resources like /book/<title> .

Core Components

  • Flask-JWT Integration:

    jwt = JWT(app, authenticate, identity)  # /auth
    

    Initializes the /auth endpoint with authenticate and identity callbacks .

  • Authenticate Function:
    Validates credentials against stored users:

    def authenticate(username, password):
        user = UserModel.find_by_username(username)
        if user and safe_str_cmp(user.password, password):
            return user
    
  • Identity Function:
    Retrieves a user from the JWT payload:

    def identity(payload):
        user_id = payload['identity']
        return UserModel.find_by_id(user_id)
    
  • User Registration:
    Endpoint for creating users before authentication .

Step-by-Step Authentication Flow

  1. Register a New User (if needed) via POST /register.
  2. Request a JWT by POST /auth with JSON credentials.
  3. Access Protected Endpoints using Authorization: JWT <access_token> header.

Sequence Diagram

sequenceDiagram
    participant Client
    participant API
    participant DB
    Client->>API: POST /register {username, password}
    API->>DB: save new User
    DB-->>API: user saved
    API-->>Client: 201 Created

    Client->>API: POST /auth {username, password}
    API->>API: authenticate()
    API->>DB: find_by_username()
    DB-->>API: return user
    API-->>Client: {access_token}

    Client->>API: GET /book/<title> + JWT token
    API->>API: identity()
    API->>DB: find_by_id()
    DB-->>API: return user
    API->>API: authorize
    API-->>Client: 200 OK, book data

Authentication Endpoint – Obtain JWT

POST /auth

{
    "title": "Obtain JWT Token",
    "description": "Authenticate user credentials and receive a JWT token",
    "method": "POST",
    "baseUrl": "http://localhost:5000",
    "endpoint": "/auth",
    "headers": [
        {
            "key": "Content-Type",
            "value": "application/json",
            "required": true
        }
    ],
    "bodyType": "json",
    "requestBody": "{\n  \"username\": \"<your_username>\",\n  \"password\": \"<your_password>\"\n}",
    "responses": {
        "200": {
            "description": "Token generated successfully",
            "body": "{\n  \"access_token\": \"<jwt_token>\"\n}"
        },
        "401": {
            "description": "Invalid credentials",
            "body": "{\n  \"description\": \"Invalid credentials\"\n}"
        }
    }
}

User Registration – Prerequisite

POST /register

{
    "title": "User Registration",
    "description": "Create a new user account for authentication",
    "method": "POST",
    "baseUrl": "http://localhost:5000",
    "endpoint": "/register",
    "headers": [
        {
            "key": "Content-Type",
            "value": "application/json",
            "required": true
        }
    ],
    "bodyType": "json",
    "requestBody": "{\n  \"username\": \"<your_username>\",\n  \"password\": \"<your_password>\"\n}",
    "responses": {
        "201": {
            "description": "User created successfully",
            "body": "{\n  \"message\": \"User created successfully.\"\n}"
        },
        "400": {
            "description": "Username already exists",
            "body": "{\n  \"message\": \"A user with that username already exists\"\n}"
        }
    }
}

Using the JWT Token

After obtaining access_token, include it in your request headers:

curl -H "Authorization: JWT <access_token>" \
     http://localhost:5000/book/<title>

Protected Endpoint Example

Books and stores resources use @jwt_required() to enforce authentication:

@jwt_required()
def get(self, title):
    book = BookModel.find_by_title(title)
    if book:
        return book.json()
    return {'message': 'book not found'}, 404

Common Errors

  • Missing Authorization header → 401 Unauthorized
  • Invalid or expired token → 401 Invalid token
  • Unauthorized access to non-protected routes is allowed.

Best Practices

  • Secure app.secret_key via environment variables.
  • Use HTTPS in production to protect tokens in transit.
  • Implement token expiration for enhanced security.
{
    "title": "🔒 Security Tip",
    "content": "Store `app.secret_key` in environment variables, not source code."
}