Authentication
JWT authentication system for the Colurs API.
All endpoints require the x-api-key header for authorization.
Login / Get Token
Authenticates a user and returns JWT tokens (access and refresh).
Endpoint
POST /token/Required Headers
Content-Type: application/json
Accept: application/json
x-api-key: [API_KEY]Request Body
| Field | Type | Required | Description |
|---|---|---|---|
username | string | ✅ | Email or username |
password | string | ✅ | Password |
platform | string | ❌ | API, APP, PANEL, IOS, ANDROID (default: API) |
code | string | ⚠️ | Verification code (required for PANEL, IOS, ANDROID) |
otp | string | ⚠️ | 6-digit 2FA code (if user has MFA enabled) |
Important: For PANEL, IOS, and ANDROID platforms, an additional verification code stored in cache is required.
cURL Example
curl -X POST https://dev.backend.colurs.co/token/ \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "x-api-key: [API_KEY]" \
-d '{
"username": "user@example.com",
"password": "Password123!",
"platform": "API"
}'Response
{
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}Possible Errors
| Code | Error | Description |
|---|---|---|
400 | DataInvalidException | Invalid credentials or invalid platform |
400 | CodeMustBeRequiredException | Code required for PANEL/IOS/ANDROID |
400 | CodeExpiredException | Verification code expired |
400 | OTPRequiredException | 2FA code required (user has MFA) |
400 | InvalidOTPException | Invalid 2FA code |
Using the Token
The access token expires in 15 minutes. Use the refresh token to get a new one.
For endpoints requiring authentication, include the token in the header:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...Complete Headers for Authenticated Requests
Content-Type: application/json
Accept: application/json
x-api-key: [API_KEY]
Authorization: Bearer [ACCESS_TOKEN]Refresh Token
Use this endpoint when the access token expires to get a new one without re-authenticating.
Endpoint
POST /token/refresh/Request
{
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}Response
{
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}The refresh token has a very long duration (10,000 days), but it’s recommended to handle it securely.
JWT Configuration
| Parameter | Value |
|---|---|
| Access Token Lifetime | 15 minutes |
| Refresh Token Lifetime | 10,000 days |
| Algorithm | HS256 |
Supported Platforms
| Platform | Description | Requires Code |
|---|---|---|
API | External API integration | ❌ |
APP | Main mobile application | ❌ |
PANEL | Administrative web panel | ✅ |
IOS | iOS application | ✅ |
ANDROID | Android application | ✅ |
Authentication with 2FA (MFA)
If the user has two-factor authentication enabled (totp_secret field in profile), the login flow requires an additional step.
Step 1: Normal login
Send username, password, and platform to /token/ endpoint.
{
"username": "user@example.com",
"password": "Password123!",
"platform": "API"
}Step 2: Receive OTPRequired error
If user has 2FA enabled, you’ll receive:
{
"code_transaction": "OTPRequiredException",
"message": "OTP code required"
}Step 3: Resend with OTP code
Send the same request adding the otp field with the 6-digit code from the authenticator:
{
"username": "user@example.com",
"password": "Password123!",
"platform": "API",
"otp": "123456"
}Step 4: Get tokens
If the OTP code is correct, you’ll receive the access tokens.
{
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}The OTP code is generated using TOTP (Time-based One-Time Password) with the pyotp library. Compatible with Google Authenticator, Authy, etc.
Authentication for PANEL/IOS/ANDROID
For PANEL, IOS, and ANDROID platforms, an additional verification code is required, which is sent to the user and temporarily stored in cache.
Step 1: Request verification code
User requests a code that is sent to their email/phone.
Step 2: Code is stored in cache
The system stores the code associated with the user’s username.
Step 3: Login with code
{
"username": "user@example.com",
"password": "Password123!",
"platform": "PANEL",
"code": "ABC123"
}Step 4: Validation
The system verifies that the code matches the one stored in cache.
Logout
JWT is stateless. Logout is handled by deleting tokens on the client.
There’s no logout endpoint. To “sign out”:
- Delete the
accesstoken from local storage - Delete the
refreshtoken from local storage - Redirect user to login screen
Security note: JWT tokens remain valid until expiration. If you need to invalidate a token immediately, consider implementing a token blacklist on the server.
Default Permissions
The system has the following global permissions configured in REST_FRAMEWORK:
DEFAULT_PERMISSION_CLASSES = (
"rest_framework_api_key.permissions.HasAPIKey",
"rest_framework.permissions.IsAuthenticated",
)This means that, by default, all endpoints require:
- ✅ Valid API Key (
x-api-keyheader) - ✅ Authenticated user (
Authorization: Bearerheader)
Specific exceptions are defined in each view.