HTTP Basic Auth¶
Docs: https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Authentication
Warning
HTTP Basic Auth is very insecure. It is better than nothing, but is enough for nearly all real use-cases. Please, consider using JWT Auth instead.
Requiring auth¶
To work with HTTP Basic auth you would need to subclass either
HttpBasicSyncAuth or
HttpBasicAsyncAuth
and override its sync or async (respectively) authenticate method,
which will decide whether or not passed username and password are correct.
Here’s how to do it:
1from typing import Any
2
3from django.conf import settings
4from typing_extensions import override
5
6from dmr import Controller
7from dmr.endpoint import Endpoint
8from dmr.security.http import HttpBasicAsyncAuth
9from dmr.serializer import BaseSerializer
10
11
12class HttpBasicAsync(HttpBasicAsyncAuth):
13 @override
14 async def authenticate(
15 self,
16 endpoint: 'Endpoint',
17 controller: 'Controller[BaseSerializer]',
18 username: str,
19 password: str,
20 ) -> Any | None:
21 # Define `HTTP_BASIC_USERNAME` and `HTTP_BASIC_PASSWORD`
22 # in your settings.py file:
23 if (
24 username == settings.HTTP_BASIC_USERNAME
25 and password == settings.HTTP_BASIC_PASSWORD
26 ):
27 return True
28 return None
Let’s say we defined a horribly weak set
of username and password: admin / pass.
Let’s check that the auth works:
1from typing import TypedDict
2
3from dmr import Body, Controller
4from dmr.plugins.pydantic import PydanticSerializer
5from examples.auth.http_basic.auth import HttpBasicAsync
6
7
8class _RequestModel(TypedDict):
9 bill: str
10
11
12class BillController(
13 Controller[PydanticSerializer],
14):
15 auth = (HttpBasicAsync(),)
16
17 async def post(self, parsed_body: Body[_RequestModel]) -> str:
18 return f'Processing bill: {parsed_body["bill"]}'
19
Run result
$ curl http://127.0.0.1:8000/api/username/ -D - -X POST -d '{"bill": "parking"}' -H 'Content-Type: application/json'
HTTP/1.1 401 Unauthorized
date: Sun, 29 Mar 2026 18:52:13 GMT
server: uvicorn
Content-Type: application/json
X-Frame-Options: DENY
Vary: Accept-Language
Content-Language: en
Content-Length: 58
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
Cross-Origin-Opener-Policy: same-origin
{"detail":[{"msg":"Not authenticated","type":"security"}]}
$ curl http://127.0.0.1:8000/api/username/ -X POST -d '{"bill": "parking"}' -H 'Content-Type: application/json' -H 'Authorization: Basic YWRtaW46cGFzcw=='
"Processing bill: parking"
Any other authentication method will be better than the one above. Consider using JWT Auth instead.
API Reference¶
- class dmr.security.http.HttpBasicSyncAuth(*, security_scheme_name: str = 'http_basic', header: str = 'Authorization')[source]¶
Uses HTTP Basic Auth.
Subclass this type to provide actual username/password check according to your needs. This class is used for sync endpoints.
Warning
HTTP Basic Auth is not really secure and should not be used for anything serious. Consider using JWT instead.
See also
https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Authentication#basic_authentication_scheme
- __call__(endpoint: Endpoint, controller: Controller[BaseSerializer]) Any | None[source]¶
Does the login routine.
- abstractmethod authenticate(endpoint: Endpoint, controller: Controller[BaseSerializer], username: str, password: str) Any | None[source]¶
Override this method to provide an actual user/password check.
- classmethod provide_response_specs(metadata: EndpointMetadata, controller_cls: type[Controller[BaseSerializer]], existing_responses: Mapping[HTTPStatus, ResponseSpec]) list[ResponseSpec]¶
Provides responses that can happen when user is not authed.
- property security_schemes: dict[str, SecurityScheme | Reference]¶
Provides a security schema definition.
- class dmr.security.http.HttpBasicAsyncAuth(*, security_scheme_name: str = 'http_basic', header: str = 'Authorization')[source]¶
Uses HTTP Basic Auth.
Subclass this type to provide actual username/password check according to your needs. This class is used for async endpoints.
Warning
HTTP Basic Auth is not really secure and should not be used for anything serious. Consider using JWT instead.
See also
https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Authentication#basic_authentication_scheme
- async __call__(endpoint: Endpoint, controller: Controller[BaseSerializer]) Any | None[source]¶
Does the login routine.
- abstractmethod async authenticate(endpoint: Endpoint, controller: Controller[BaseSerializer], username: str, password: str) Any | None[source]¶
Override this method to provide an actual user/password check.
- classmethod provide_response_specs(metadata: EndpointMetadata, controller_cls: type[Controller[BaseSerializer]], existing_responses: Mapping[HTTPStatus, ResponseSpec]) list[ResponseSpec]¶
Provides responses that can happen when user is not authed.
- property security_schemes: dict[str, SecurityScheme | Reference]¶
Provides a security schema definition.