Overview
The RestAPI project uses JSON Web Token (JWT) authentication powered by Simple JWT . This provides a secure, stateless authentication mechanism for all API endpoints.
JWT authentication is configured in RestAPI/settings.py:203-214 with an 8-hour token lifetime.
How JWT Authentication Works
User Login
The client sends credentials (email/password) to obtain access and refresh tokens.
Token Storage
The client stores the access token securely (e.g., in memory or secure storage).
Authenticated Requests
The client includes the access token in the Authorization header for all subsequent requests.
Token Refresh
When the access token expires (after 8 hours), use the refresh token to obtain a new access token.
Configuration
The JWT authentication is configured in RestAPI/settings.py with the following settings:
REST_FRAMEWORK = {
'DEFAULT_SCHEMA_CLASS' : 'rest_framework.schemas.coreapi.AutoSchema' ,
'DEFAULT_AUTHENTICATION_CLASSES' : [
'rest_framework_simplejwt.authentication.JWTAuthentication' ,
],
}
# Token validity configuration
from datetime import timedelta
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME' : timedelta( hours = 8 ),
}
Key Features
Access Token Lifetime : 8 hours
Authentication Class : JWTAuthentication
Stateless : No server-side session storage required
Secure : Tokens are cryptographically signed
Obtaining Tokens
Note : The current implementation uses a custom user model with SHA-256 hashed passwords. You’ll need to implement token endpoints using Simple JWT’s views or create custom authentication endpoints.
Standard Simple JWT Endpoints
To enable JWT token endpoints, add the following to your RestAPI/urls.py:
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
)
urlpatterns = [
path( 'admin/' , admin.site.urls),
path( 'Database/' , include( 'task_aplication.urls' )),
# JWT Authentication endpoints
path( 'api/token/' , TokenObtainPairView.as_view(), name = 'token_obtain_pair' ),
path( 'api/token/refresh/' , TokenRefreshView.as_view(), name = 'token_refresh' ),
]
Obtain Access Token
curl -X POST http://localhost:8000/api/token/ \
-H "Content-Type: application/json" \
-d '{
"username": "[email protected] ",
"password": "your_password"
}'
Response:
{
"access" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ,
"refresh" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Making Authenticated Requests
Include the access token in the Authorization header with the Bearer prefix:
curl -X GET http://localhost:8000/Database/usuarios/ \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
Refreshing Tokens
When your access token expires (after 8 hours), use the refresh token to obtain a new access token:
curl -X POST http://localhost:8000/api/token/refresh/ \
-H "Content-Type: application/json" \
-d '{
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}'
Response:
{
"access" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
User Model
The custom Usuario model is defined in task_aplication/models.py:55-81 with the following key fields:
task_aplication/models.py
class Usuario ( models . Model ):
id_usuario = models.AutoField( primary_key = True )
rol_usuario = models.ForeignKey(RolUsuario, on_delete = models. CASCADE )
email = models.CharField( max_length = 50 )
placa = models.CharField( max_length = 8 , null = True , blank = True )
contrasena = models.CharField( max_length = 64 ) # SHA-256 hash
token_notificacion = models.TextField()
fecha_creacion = models.DateField( auto_now_add = True )
fecha_modificacion = models.DateField( auto_now = True )
id_ciudad = models.ForeignKey(Ciudad, on_delete = models. CASCADE , default = 1 )
id_pais = models.ForeignKey(Pais, on_delete = models. CASCADE , default = 1 )
estado = models.IntegerField( choices = [
( 0 , 'Inactivo' ),
( 1 , 'Activo' ),
( 3 , 'deshabilitado' )
], default = 0 )
def save ( self , * args , ** kwargs ):
# Hash password with SHA-256 on creation
if not self .id_usuario:
self .contrasena = self ._hash_password( self .contrasena)
super ().save( * args, ** kwargs)
def _hash_password ( self , password ):
sha256 = hashlib.sha256()
sha256.update(password.encode( 'utf-8' ))
return sha256.hexdigest()
The current implementation uses SHA-256 for password hashing. For production use, consider migrating to Django’s built-in password hashers which use PBKDF2 with stronger security.
CORS Configuration
The API includes CORS support via django-cors-headers configured in RestAPI/settings.py:38-89:
Development Mode (DEBUG=True)
CORS_ALLOW_ALL_ORIGINS = True
ALLOWED_HOSTS = [ '*' ]
CORS_ALLOW_HEADERS = [ '*' ]
Production Mode (DEBUG=False)
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_ALL_ORIGINS = False
CORS_ALLOWED_ORIGINS = [
'migoadvs.pythonanywhere.com' ,
]
ALLOWED_HOSTS = [
'localhost' ,
'127.0.0.1' ,
'migoadvs.pythonanywhere.com' ,
]
Allowed Methods and Headers
CORS_ALLOW_METHODS = (
'GET' ,
'OPTIONS' ,
'PATCH' ,
'POST' ,
'PUT' ,
'DELETE' ,
)
CORS_ALLOW_HEADERS = (
'accept' ,
'accept-encoding' ,
'authorization' , # Required for JWT
'content-type' ,
'dnt' ,
'origin' ,
'user-agent' ,
'x-csrftoken' ,
'x-requested-with' ,
)
Error Responses
Invalid Credentials
{
"detail" : "No active account found with the given credentials"
}
Expired Token
{
"detail" : "Given token not valid for any token type" ,
"code" : "token_not_valid" ,
"messages" : [
{
"token_class" : "AccessToken" ,
"token_type" : "access" ,
"message" : "Token is invalid or expired"
}
]
}
Missing Token
{
"detail" : "Authentication credentials were not provided."
}
Security Best Practices
Never store tokens in localStorage or sessionStorage in web applications
Use httpOnly cookies or secure in-memory storage
For mobile apps, use secure storage mechanisms (Keychain on iOS, KeyStore on Android)
Always use HTTPS in production
Never send tokens in URL parameters
Always use the Authorization header with Bearer prefix
Implement token refresh logic before expiration (8-hour lifetime)
Handle token expiration gracefully with automatic refresh
Clear tokens on logout
Keep your DJANGO_KEY secret and unique
Use environment variables for sensitive configuration
Never commit .env files to version control
Rotate secrets regularly
Next Steps
API Reference Explore authenticated API endpoints
User Management Learn about user registration and management