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 not enough for nearly all real use-cases. Please, consider using JWT Auth instead.

The only reasonable use-case for this auth is to use HTTP Basic auth for protecting some public things like API status dashboards.

Note that this auth type does not set request.user by design. Because many users might use the same auth parameters.

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:

Let’s say we defined a horribly weak set of username and password: admin / pass. Let’s check that the auth works:

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: Fri, 16 Oct 2026 22:52:46 GMT
server: uvicorn
WWW-Authenticate: Basic realm="api", charset="UTF-8"
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"

OpenAPI Schema

Preview openapi.json
{
  "components": {
    "schemas": {
      "ErrorDetail": {
        "description": "Base schema for error details description.",
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "string"
                }
              ]
            },
            "title": "Loc",
            "type": "array"
          },
          "msg": {
            "title": "Msg",
            "type": "string"
          },
          "type": {
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "msg"
        ],
        "title": "ErrorDetail",
        "type": "object"
      },
      "ErrorModel": {
        "description": "Default error response schema.\n\nCan be customized.\nSee :ref:`customizing-error-messages` for more details.",
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ErrorDetail"
            },
            "title": "Detail",
            "type": "array"
          }
        },
        "required": [
          "detail"
        ],
        "title": "ErrorModel",
        "type": "object"
      },
      "_RequestModel": {
        "properties": {
          "bill": {
            "title": "Bill",
            "type": "string"
          }
        },
        "required": [
          "bill"
        ],
        "title": "_RequestModel",
        "type": "object"
      }
    },
    "securitySchemes": {
      "http_basic": {
        "description": "Http Basic auth",
        "scheme": "basic",
        "type": "http"
      }
    }
  },
  "info": {
    "title": "Django Modern Rest",
    "version": "0.1.0"
  },
  "openapi": "3.2.0",
  "paths": {
    "/api/billcontroller/": {
      "post": {
        "operationId": "postBillControllerApiBillcontroller",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/_RequestModel"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "description": "Created"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Raised when request components cannot be parsed"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Raised when auth was not successful",
            "headers": {
              "WWW-Authenticate": {
                "description": "Challenges that the client can use to authenticate this request",
                "required": true,
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "406": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Raised when provided `Accept` header cannot be satisfied"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Raised when returned response does not match the response schema"
          }
        },
        "security": [
          {
            "http_basic": []
          }
        ]
      }
    }
  }
}

Any other authentication method will be better than the one above. Consider using JWT Auth instead.

Customization#

Added in version 0.15.0.

You can customize:

  • Security scheme name, default: http_basic

  • Header name, default: Authorization

  • Header value prefix (auth_scheme), default: Basic

  • The WWW-Authenticate challenge (www_authenticate and realm), see How authentication works

The header value must always start with the auth_scheme prefix, which is matched exactly. So, with the default settings only Authorization: Basic <base64(username:password)> is accepted, while Authorization: basic <base64(username:password)> and a bare Authorization: <base64(username:password)> are not.

Pass auth_scheme='' if you need to read the credentials without any prefix at all, this is how older versions worked.

Headers with a different prefix are left to the next auth in the chain. But, when the prefix does match and the credentials still cannot be decoded, NotAuthenticatedError is raised right away and no other auth classes are tried.

See API reference.