Skip to content

Authentication

Fastpy includes a complete JWT authentication system with refresh tokens.

Overview

🎫

Access Tokens

Short-lived (30 min), for API access

🔄

Refresh Tokens

Long-lived (7 days), for renewal

🔒

Password Hashing

bcrypt with automatic salting

Endpoints

EndpointMethodDescription
/api/auth/registerPOSTCreate new user
/api/auth/loginPOSTLogin (form data, OAuth2 compatible)
/api/auth/login/jsonPOSTLogin (JSON body)
/api/auth/refreshPOSTRefresh access token
/api/auth/meGETGet current user
/api/auth/change-passwordPOSTChange password
/api/auth/forgot-passwordPOSTRequest password reset
/api/auth/reset-passwordPOSTReset password
/api/auth/verify-emailPOSTVerify email
/api/auth/logoutPOSTLogout

Registration

bash
curl -X POST http://localhost:8000/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "securepassword123",
    "name": "John Doe"
  }'

Response:

json
{
  "success": true,
  "data": {
    "user": {
      "id": 1,
      "email": "user@example.com",
      "name": "John Doe"
    },
    "access_token": "eyJ...",
    "refresh_token": "eyJ...",
    "token_type": "bearer"
  }
}

Login

bash
# Works with Swagger UI's Authorize button
curl -X POST http://localhost:8000/api/auth/login \
  -d "username=user@example.com&password=securepassword123"
bash
curl -X POST http://localhost:8000/api/auth/login/json \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "securepassword123"
  }'

Response:

json
{
  "success": true,
  "data": {
    "access_token": "eyJ...",
    "refresh_token": "eyJ...",
    "token_type": "bearer",
    "expires_in": 1800
  }
}

Refresh Token

bash
curl -X POST http://localhost:8000/api/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{
    "refresh_token": "eyJ..."
  }'

Protected Routes

Using the Auth Dependency

python
from app.utils.auth import get_current_active_user
from app.models.user import User

@router.get("/profile")
async def get_profile(
    current_user: User = Depends(get_current_active_user)
):
    return success_response(data=current_user)

Making API Requests

bash
curl http://localhost:8000/api/users \
  -H "Authorization: Bearer eyJ..."

Configuration

bash
# .env
SECRET_KEY=your-super-secret-key-minimum-32-characters
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30
REFRESH_TOKEN_EXPIRE_DAYS=7

Password Utilities

Hashing

python
from app.utils.auth import get_password_hash

hashed = get_password_hash("mypassword")

Verification

python
from app.utils.auth import verify_password

is_valid = verify_password("mypassword", hashed_password)

Token Structure

Access Token Payload

json
{
  "sub": "1",
  "email": "user@example.com",
  "type": "access",
  "exp": 1704067200,
  "iat": 1704065400
}

Refresh Token Payload

json
{
  "sub": "1",
  "type": "refresh",
  "exp": 1704672000,
  "iat": 1704065400
}

Error Responses

Invalid Credentials

json
{
  "success": false,
  "error": {
    "message": "Invalid email or password",
    "code": "INVALID_CREDENTIALS"
  }
}

Token Expired

json
{
  "success": false,
  "error": {
    "message": "Token has expired",
    "code": "TOKEN_EXPIRED"
  }
}

Unauthorized

json
{
  "success": false,
  "error": {
    "message": "Not authenticated",
    "code": "UNAUTHORIZED"
  }
}

Security Best Practices

Important

Always follow these practices in production environments.

🔐
Use HTTPS

Always use TLS/SSL in production

🔑
Rotate SECRET_KEY

Change your secret key periodically

⏱️
Short Token Lifetime

Keep access tokens to 15-30 minutes

🍪
Secure Storage

Use httpOnly cookies for refresh tokens

🚫
Token Blacklisting

Invalidate tokens on logout

💪
Strong Passwords

Enforce minimum 8 characters

Released under the MIT License.