django-ninja-jwt: Bug Report: Inconsistent Response Format for User Authentication in Django
Description
I am implementing a user authentication system in Django, utilizing a standard response format for all API responses. This standard format includes message, success, data, and trace_id. While this format is correctly applied for successful authentication, it fails to be consistent for authentication errors.
Expected Behavior
For both successful and failed authentication attempts, the response should adhere to the following format:
{
"message": "string or null",
"success": true or false,
"data": { /* relevant data or empty */ },
"trace_id": "string"
}
Current Behavior
- get token request
curl -X 'POST' \
'http://127.0.0.1:8000/api/token/pair' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"password": "12345",
"username": "testuser"
}'
-
Successful Authentication Response:
{ "message": null, "success": true, "data": { "refresh": "token", "access": "token", "user": { "first_name": "name", "email": "email" } }, "trace_id": "string" }This response is as per the expected format.
-
Failed Authentication Response:
{ "detail": "{'detail': ErrorDetail(string='No active account found with the given credentials', code=''), 'code': ErrorDetail(string='', code='')}", "trace_id": "string" }This response does not match the standard format, particularly lacking the
messageandsuccessfields. -
refresh token request
curl -X 'POST' \
'http://127.0.0.1:8000/api/token/pair' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"password": "12345",
"username": "testuser"
}'
- refresh token response
{
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTcwMDE1MzQ4OCwiaWF0IjoxNzAwMDY3MDg4LCJqdGkiOiIzMjU4YjNiYTkyNGE0MjJjOGJiYWRkOTViOTM0MzU1MCIsInVzZXJfaWQiOjF9.tBbo_coSHRo96XmSmdZQjl-Gf2VH5QXb0ZN1AFd_CeA",
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzAwMDY3NDcwLCJpYXQiOjE3MDAwNjcwODgsImp0aSI6ImQ0YWY0MzcyYWMzYjQzNzliZGNhYzg4ZjBiZmU0ZGYyIiwidXNlcl9pZCI6MX0.u6ryxuI_kn9RJXK9QJAVcqJSLqPlJeJRqgmQYgdu_9Y",
"trace_id": "680dc33ef9c149919b6a9ec15d653d16"
}
Code Snippets
- Custom Schema for Responses:
# core.schemas.py
from pydantic.generics import GenericModel
class ErrorMsg(BaseModel):
message: Optional[str] = None
success: bool = True
GenericResultsType = TypeVar("GenericResultsType")
class StandResponse(ErrorMsg, GenericModel, Generic[GenericResultsType]):
data: GenericResultsType
# custom_token_out.py
from core.schemas import StandResponse
class MyTokenObtainPairOutSchema(Schema):
refresh: str
access: str
user: UserSchema
class MyTokenObtainPairInputSchema(TokenObtainInputSchemaBase):
@classmethod
def get_response_schema(cls) -> Type[Schema]:
return StandResponse[MyTokenObtainPairOutSchema]
@classmethod
def get_token(cls, user) -> Dict:
values = {}
refresh = RefreshToken.for_user(user)
values["refresh"] = str(refresh)
values["access"] = str(refresh.access_token)
values.update(
user=UserSchema.from_orm(user)
)
return {'data': values}
Steps to Reproduce
- Configure the Django application with the mentioned response format.
- Implement custom user authentication handling with the provided schemas.
- Authenticate with valid credentials to observe the correct format.
- Authenticate with invalid credentials to observe the deviation.
Possible Solution
I need guidance on customizing the response format for failed authentication attempts to conform to our standard response format. This might involve modifying the exception handling process within the Django authentication framework or adjusting our custom schema.
About this issue
- Original URL
- State: closed
- Created 8 months ago
- Comments: 20 (9 by maintainers)
Sorry, I’m so busy in past several days. Pls close it.
thx, it works.