{"record":{"id":"8d9d29279d5aba54","repo":"tiangolo/fastapi","slug":"not-authenticated-8d9d29","errorCode":null,"errorMessage":"Not authenticated","messagePattern":"Not authenticated","errorType":"http","errorClass":"HTTPException","httpStatus":401,"severity":"error","filePath":"docs_src/security/tutorial003_py310.py","lineNumber":59,"sourceCode":"\n\ndef get_user(db, username: str):\n    if username in db:\n        user_dict = db[username]\n        return UserInDB(**user_dict)\n\n\ndef fake_decode_token(token):\n    # This doesn't provide any security at all\n    # Check the next version\n    user = get_user(fake_users_db, token)\n    return user\n\n\nasync def get_current_user(token: str = Depends(oauth2_scheme)):\n    user = fake_decode_token(token)\n    if not user:\n        raise HTTPException(\n            status_code=status.HTTP_401_UNAUTHORIZED,\n            detail=\"Not authenticated\",\n            headers={\"WWW-Authenticate\": \"Bearer\"},\n        )\n    return user\n\n\nasync def get_current_active_user(current_user: User = Depends(get_current_user)):\n    if current_user.disabled:\n        raise HTTPException(status_code=400, detail=\"Inactive user\")\n    return current_user\n\n\n@app.post(\"/token\")\nasync def login(form_data: OAuth2PasswordRequestForm = Depends()):\n    user_dict = fake_users_db.get(form_data.username)\n    if not user_dict:\n        raise HTTPException(status_code=400, detail=\"Incorrect username or password\")","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/tiangolo/fastapi/blob/3e8d1526d83a90aaf7d6eb6dc682bf150f180b25/docs_src/security/tutorial003_py310.py#L41-L77","documentation":"Raised by get_current_user when fake_decode_token(token) returns None, i.e. the bearer token does not map to any user. It carries WWW-Authenticate: Bearer so clients re-prompt. Distinguish this from the automatic 401 that OAuth2PasswordBearer itself raises (same default detail 'Not authenticated') when the Authorization header is missing entirely — this line fires only when a token was supplied but did not resolve.","triggerScenarios":"GET /users/me with Authorization: Bearer <value> where <value> is not a fake_users_db key (not 'johndoe'/'alice'), or 'Bearer ' with an empty token. Because this fake implementation treats the token AS the username, any non-username token fails.","commonSituations":"Client sent an opaque or stale token; developer confused that there is no real validation (token==username); a token minted before the user was deleted from the db.","solutions":["Send a token obtained from POST /token (here, literally the username 'johndoe').","In Swagger UI, use Authorize and complete the OAuth2 password flow before calling protected routes.","Replace fake_decode_token with real JWT verification before trusting this path in anything beyond the tutorial."],"exampleFix":"// before\nuser = fake_decode_token(token)\nif not user:\n    raise HTTPException(status_code=401, detail=\"Not authenticated\", headers={\"WWW-Authenticate\": \"Bearer\"})\n\n// after (real JWT)\npayload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])\nuser = get_user(db, payload.get(\"sub\"))\nif user is None:\n    raise HTTPException(status_code=401, detail=\"Not authenticated\", headers={\"WWW-Authenticate\": \"Bearer\"})","handlingStrategy":"validation","validationCode":"# Ensure a non-empty bearer token maps to a known user before the call\nKNOWN_USERS = {\"johndoe\", \"alice\"}\ndef token_resolves(token: str) -> bool:\n    return bool(token) and token in KNOWN_USERS","typeGuard":"from typing import TypeGuard\ndef is_known_token(token: str) -> TypeGuard[str]:\n    return isinstance(token, str) and token in {\"johndoe\", \"alice\"}","tryCatchPattern":"import httpx\ntry:\n    r = httpx.get(\"/users/me\", headers={\"Authorization\": f\"Bearer {token}\"})\nexcept httpx.HTTPStatusError as e:\n    if e.response.status_code == 401:\n        # re-run the OAuth2 password flow to obtain a fresh token\n        token = login_and_get_token()","preventionTips":["Always obtain the token from POST /token rather than hand-typing one.","In Swagger UI, use Authorize to complete the OAuth2 flow before calling protected routes.","Replace the fake 'token==username' decode with real JWT verification before relying on it."],"tags":["fastapi","authentication","oauth2","bearer","python"],"backgroundTag":null,"analyzedSha":"3e8d1526d83a90aaf7d6eb6dc682bf150f180b25","analyzedAt":"2026-08-11T02:34:52.986Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}