---
title: "Authentication"
description: "Authenticate API requests with a bearer token: a static token or an access token from the OAuth 2.0 authorization code flow."
canonical: authentication.html
---

<a id="usage-authentication"></a>

<a id="authentication"></a>

# Authentication

Send a bearer token in the `Authorization` header. The token is the static token
of an app or an OAuth access token:

```bash
curl -H 'Authorization: Bearer <token>' \
    'https://example.org/typo3/api/v1/records/pages?limit=10'
```

The request uses the backend user of the token. All permissions of that user
apply, in addition to the scopes of the app.

In the TYPO3 backend, JavaScript calls the API in the session of the logged-in
user, see [Calling the API from backend JavaScript](javascript.md#usage-javascript).

<a id="usage-oauth"></a>

<a id="oauth-2-0"></a>

## OAuth 2.0

OAuth apps use the authorization code flow. The implementation uses
`league/oauth2-server`:

1. **Send the user to the authorization endpoint**
   The app sends the backend user to the authorization endpoint
   `/typo3/oauth/authorize` with the parameters `response_type=code`,
   `client_id`, `redirect_uri`, `scope` (separated by spaces) and
   `state`. The flow also supports the PKCE parameters
   (`code_challenge`, `code_challenge_method`).
2. **Log in and approve access**
   If the user is not logged in, the user logs in to the TYPO3 backend.
   The user then approves or denies access on the consent screen. The
   consent screen lists the requested scopes that the app record selects
   and that the user can have.
3. **Receive the code**
   TYPO3 redirects the user to the redirect URI with an authorization
   code, which is valid for 10 minutes.
4. **Exchange the code for tokens**
   The app exchanges the code for an access token and a refresh token at
   the token endpoint `/typo3/api/v1/oauth/token`. It authenticates with
   the client ID and the client secret (HTTP Basic authentication).
5. **Call the API**
   The app calls the API with the access token. An access token is valid
   for one hour. After this time, the app gets a new access token at the
   token endpoint, with `grant_type=refresh_token` and the refresh
   token.

Apps are confidential clients. They exchange the code on their server, because
a browser must not get the client secret. For this reason, the token endpoint
and the API send no CORS headers.

```diagram
sequence canvas=940
title "An OAuth app gets its tokens after the backend user approves the access"
description "The app sends the backend user to the authorization endpoint. The user logs in and approves the access, TYPO3 redirects with a code, the app exchanges the code for tokens and calls the API. After an hour it gets a new access token with the refresh token at the token endpoint."

lane app "App"
lane user "Backend user"
  person
lane typo3 "TYPO3"
phase "Authorization"
  app -> user "Redirect to /typo3/oauth/authorize"
  user -> typo3 "Log in and approve access"
  typo3 -> app "Redirect with a code, valid for 10 minutes"
phase "Token"
  app => typo3 "Code and client credentials for an access and a refresh token"
phase "API"
  app -> typo3 "Request with the access token"
phase "Refresh"
  app => typo3 "After one hour: refresh token for a new access token"
```

*The app does not see the password of the backend user. It gets only the tokens at the end of the authorization.*

Clients find the endpoints and the supported scopes in the OAuth 2.0
Authorization Server Metadata
([RFC 8414](https://datatracker.ietf.org/doc/html/rfc8414)) at
`/.well-known/oauth-authorization-server`.
