mirror of
				https://github.com/fastapi-users/fastapi-users.git
				synced 2025-11-04 06:37:51 +08:00 
			
		
		
		
	* Implement Transport classes * Implement authentication strategy classes * Revamp authentication with Transport and Strategy * Revamp strategy and OAuth so that they can use a callable dependency * Update docstring * Make ErrorCode a proper Enum and cleanup unused OpenAPI utils * Remove useless check * Tweak typing in authenticator * Update docs * Improve logout/destroy token logic * Update docs * Update docs * Update docs and full examples * Apply formatting to examples * Update OAuth doc and examples * Add migration doc * Implement Redis session token * Add Redis Session documentation * RedisSession -> Redis * Fix links in docs
		
			
				
	
	
		
			408 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			408 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
# Flow
 | 
						|
 | 
						|
This page will present you a complete registration and authentication flow once you've setup **FastAPI Users**. Each example will be presented with a `cURL` and an `axios` example.
 | 
						|
 | 
						|
## 1. Registration
 | 
						|
 | 
						|
First step, of course, is to register as a user.
 | 
						|
 | 
						|
### Request
 | 
						|
 | 
						|
=== "cURL"
 | 
						|
    ``` bash
 | 
						|
    curl \
 | 
						|
    -H "Content-Type: application/json" \
 | 
						|
    -X POST \
 | 
						|
    -d "{\"email\": \"king.arthur@camelot.bt\",\"password\": \"guinevere\"}" \
 | 
						|
    http://localhost:8000/auth/register
 | 
						|
    ```
 | 
						|
 | 
						|
=== "axios"
 | 
						|
    ```ts
 | 
						|
    axios.post('http://localhost:8000/auth/register', {
 | 
						|
        email: 'king.arthur@camelot.bt',
 | 
						|
        password: 'guinevere',
 | 
						|
    })
 | 
						|
    .then((response) => console.log(response))
 | 
						|
    .catch((error) => console.log(error));
 | 
						|
    ```
 | 
						|
 | 
						|
### Response
 | 
						|
 | 
						|
You'll get a JSON response looking like this:
 | 
						|
 | 
						|
```json
 | 
						|
{
 | 
						|
    "id": "4fd3477b-eccf-4ee3-8f7d-68ad72261476",
 | 
						|
    "email": "king.arthur@camelot.bt",
 | 
						|
    "is_active": true,
 | 
						|
    "is_superuser": false
 | 
						|
}
 | 
						|
```
 | 
						|
 | 
						|
!!! info
 | 
						|
    Several things to bear in mind:
 | 
						|
 | 
						|
    * If you have defined other required fields in your `User` model (like a first name or a birthdate), you'll have to provide them in the payload.
 | 
						|
    * The user is active by default.
 | 
						|
    * The user cannot set `is_active` or `is_superuser` itself at registration. Only a superuser can do it by PATCHing the user.
 | 
						|
 | 
						|
## 2. Login
 | 
						|
 | 
						|
Now, you can login as this new user.
 | 
						|
 | 
						|
You can generate a [login route](../configuration/routers/auth.md) for each [authentication backend](../configuration/authentication/index.md). Each backend will have a different response.
 | 
						|
 | 
						|
### Bearer + JWT
 | 
						|
 | 
						|
#### Request
 | 
						|
 | 
						|
=== "cURL"
 | 
						|
    ``` bash
 | 
						|
    curl \
 | 
						|
    -H "Content-Type: multipart/form-data" \
 | 
						|
    -X POST \
 | 
						|
    -F "username=king.arthur@camelot.bt" \
 | 
						|
    -F "password=guinevere" \
 | 
						|
    http://localhost:8000/auth/jwt/login
 | 
						|
    ```
 | 
						|
 | 
						|
=== "axios"
 | 
						|
    ```ts
 | 
						|
    const formData = new FormData();
 | 
						|
    formData.set('username', 'king.arthur@camelot.bt');
 | 
						|
    formData.set('password', 'guinevere');
 | 
						|
    axios.post(
 | 
						|
        'http://localhost:8000/auth/jwt/login',
 | 
						|
        formData,
 | 
						|
        {
 | 
						|
            headers: {
 | 
						|
                'Content-Type': 'multipart/form-data',
 | 
						|
            },
 | 
						|
        },
 | 
						|
    )
 | 
						|
    .then((response) => console.log(response))
 | 
						|
    .catch((error) => console.log(error));
 | 
						|
    ```
 | 
						|
 | 
						|
!!! warning
 | 
						|
    Notice that we don't send it as a JSON payload here but with **form data** instead. Also, the email is provided by a field named **`username`**.
 | 
						|
 | 
						|
#### Response
 | 
						|
 | 
						|
You'll get a JSON response looking like this:
 | 
						|
 | 
						|
```json
 | 
						|
{
 | 
						|
    "access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNGZkMzQ3N2ItZWNjZi00ZWUzLThmN2QtNjhhZDcyMjYxNDc2IiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTg3ODE4NDI5fQ.anO3JR8-WYCozZ4_2-PQ2Ov9O38RaLP2RAzQIiZhteM",
 | 
						|
    "token_type": "bearer"
 | 
						|
}
 | 
						|
```
 | 
						|
 | 
						|
You can use this token to make authenticated requests as the user `king.arthur@camelot.bt`. We'll see how in the next section.
 | 
						|
 | 
						|
### Cookie + JWT
 | 
						|
 | 
						|
#### Request
 | 
						|
 | 
						|
=== "cURL"
 | 
						|
    ``` bash
 | 
						|
    curl \
 | 
						|
    -v \
 | 
						|
    -H "Content-Type: multipart/form-data" \
 | 
						|
    -X POST \
 | 
						|
    -F "username=king.arthur@camelot.bt" \
 | 
						|
    -F "password=guinevere" \
 | 
						|
    http://localhost:8000/auth/cookie/login
 | 
						|
    ```
 | 
						|
 | 
						|
=== "axios"
 | 
						|
    ```ts
 | 
						|
    const formData = new FormData();
 | 
						|
    formData.set('username', 'king.arthur@camelot.bt');
 | 
						|
    formData.set('password', 'guinevere');
 | 
						|
    axios.post(
 | 
						|
        'http://localhost:8000/auth/cookie/login',
 | 
						|
        formData,
 | 
						|
        {
 | 
						|
            headers: {
 | 
						|
                'Content-Type': 'multipart/form-data',
 | 
						|
            },
 | 
						|
        },
 | 
						|
    )
 | 
						|
    .then((response) => console.log(response))
 | 
						|
    .catch((error) => console.log(error));
 | 
						|
    ```
 | 
						|
 | 
						|
!!! warning
 | 
						|
    Notice that we don't send it as a JSON payload here but with **form data** instead. Also, the email is provided by a field named **`username`**.
 | 
						|
 | 
						|
#### Response
 | 
						|
 | 
						|
You'll get an empty response. However, the response will come with a `Set-Cookie` header (that's why we added the `-v` option in `cURL` to see them).
 | 
						|
 | 
						|
```
 | 
						|
set-cookie: fastapiusersauth=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiYzYwNjBmMTEtNTM0OS00YTI0LThiNGEtYTJhODc1ZGM1Mzk1IiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTg3ODE4OTQ3fQ.qNA4oPVYhoqrJIk-zvAyEfEVoEnP156G30H_SWEU0sU; HttpOnly; Max-Age=3600; Path=/; Secure
 | 
						|
```
 | 
						|
 | 
						|
You can make authenticated requests as the user `king.arthur@camelot.bt` by setting a `Cookie` header with this cookie.
 | 
						|
 | 
						|
!!! tip
 | 
						|
    The cookie backend is more suited for browsers, as they handle them automatically. This means that if you make a login request in the browser, it will automatically store the cookie and automatically send it in subsequent requests.
 | 
						|
 | 
						|
## 3. Get my profile
 | 
						|
 | 
						|
Now that we can authenticate, we can get our own profile data. Depending on your [authentication backend](../configuration/authentication/index.md), the method to authenticate the request will vary. We'll stick with JWT from now on.
 | 
						|
 | 
						|
### Request
 | 
						|
 | 
						|
=== "cURL"
 | 
						|
    ``` bash
 | 
						|
    export TOKEN="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNGZkMzQ3N2ItZWNjZi00ZWUzLThmN2QtNjhhZDcyMjYxNDc2IiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTg3ODE4NDI5fQ.anO3JR8-WYCozZ4_2-PQ2Ov9O38RaLP2RAzQIiZhteM";
 | 
						|
    curl \
 | 
						|
    -H "Content-Type: application/json" \
 | 
						|
    -H "Authorization: Bearer $TOKEN" \
 | 
						|
    -X GET \
 | 
						|
    http://localhost:8000/users/me
 | 
						|
    ```
 | 
						|
 | 
						|
=== "axios"
 | 
						|
    ```ts
 | 
						|
    const TOKEN = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNGZkMzQ3N2ItZWNjZi00ZWUzLThmN2QtNjhhZDcyMjYxNDc2IiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTg3ODE4NDI5fQ.anO3JR8-WYCozZ4_2-PQ2Ov9O38RaLP2RAzQIiZhteM';
 | 
						|
    axios.get(
 | 
						|
        'http://localhost:8000/users/me', {
 | 
						|
        headers: {
 | 
						|
            'Authorization': `Bearer ${TOKEN}`,
 | 
						|
        },
 | 
						|
    })
 | 
						|
    .then((response) => console.log(response))
 | 
						|
    .catch((error) => console.log(error));
 | 
						|
    ```
 | 
						|
 | 
						|
### Response
 | 
						|
 | 
						|
You'll get a JSON response looking like this:
 | 
						|
 | 
						|
```json
 | 
						|
{
 | 
						|
    "id": "4fd3477b-eccf-4ee3-8f7d-68ad72261476",
 | 
						|
    "email": "king.arthur@camelot.bt",
 | 
						|
    "is_active": true,
 | 
						|
    "is_superuser": false
 | 
						|
}
 | 
						|
```
 | 
						|
 | 
						|
!!! tip
 | 
						|
    If you use one of the [dependency callable](./current-user.md) to protect one of your own endpoint, you'll have to authenticate exactly in the same way.
 | 
						|
 | 
						|
## 4. Update my profile
 | 
						|
 | 
						|
We can also update our own profile. For example, we can change our password like this.
 | 
						|
 | 
						|
### Request
 | 
						|
 | 
						|
=== "cURL"
 | 
						|
    ``` bash
 | 
						|
    curl \
 | 
						|
    -H "Content-Type: application/json" \
 | 
						|
    -H "Authorization: Bearer $TOKEN" \
 | 
						|
    -X PATCH \
 | 
						|
    -d "{\"password\": \"lancelot\"}" \
 | 
						|
    http://localhost:8000/users/me
 | 
						|
    ```
 | 
						|
 | 
						|
=== "axios"
 | 
						|
    ```ts
 | 
						|
    axios.patch(
 | 
						|
        'http://localhost:8000/users/me',
 | 
						|
        {
 | 
						|
            password: 'lancelot',
 | 
						|
        },
 | 
						|
        {
 | 
						|
            headers: {
 | 
						|
                'Authorization': `Bearer ${TOKEN}`,
 | 
						|
            },
 | 
						|
        },
 | 
						|
    )
 | 
						|
    .then((response) => console.log(response))
 | 
						|
    .catch((error) => console.log(error));
 | 
						|
    ```
 | 
						|
 | 
						|
### Response
 | 
						|
 | 
						|
You'll get a JSON response looking like this:
 | 
						|
 | 
						|
```json
 | 
						|
{
 | 
						|
    "id": "4fd3477b-eccf-4ee3-8f7d-68ad72261476",
 | 
						|
    "email": "king.arthur@camelot.bt",
 | 
						|
    "is_active": true,
 | 
						|
    "is_superuser": false
 | 
						|
}
 | 
						|
```
 | 
						|
 | 
						|
!!! info
 | 
						|
    Once again, the user cannot set `is_active` or `is_superuser` itself. Only a superuser can do it by PATCHing the user.
 | 
						|
 | 
						|
## 5. Become a superuser 🦸🏻♂️
 | 
						|
 | 
						|
If you want to manage the users of your application, you'll have to become a **superuser**.
 | 
						|
 | 
						|
The very first superuser can only be set at **database level**: open it through a CLI or a GUI, find your user and set the `is_superuser` column/property to `true`.
 | 
						|
 | 
						|
### 5.1. Get the profile of any user
 | 
						|
 | 
						|
Now that you are a superuser, you can leverage the power of [superuser routes](./routes.md#superuser). You can for example get the profile of any user in the database given its id.
 | 
						|
 | 
						|
#### Request
 | 
						|
 | 
						|
=== "cURL"
 | 
						|
    ``` bash
 | 
						|
    curl \
 | 
						|
    -H "Content-Type: application/json" \
 | 
						|
    -H "Authorization: Bearer $TOKEN" \
 | 
						|
    -X GET \
 | 
						|
    http://localhost:8000/users/4fd3477b-eccf-4ee3-8f7d-68ad72261476
 | 
						|
    ```
 | 
						|
 | 
						|
=== "axios"
 | 
						|
    ```ts
 | 
						|
    axios.get(
 | 
						|
        'http://localhost:8000/users/4fd3477b-eccf-4ee3-8f7d-68ad72261476', {
 | 
						|
        headers: {
 | 
						|
            'Authorization': `Bearer ${TOKEN}`,
 | 
						|
        },
 | 
						|
    })
 | 
						|
    .then((response) => console.log(response))
 | 
						|
    .catch((error) => console.log(error));
 | 
						|
    ```
 | 
						|
 | 
						|
#### Response
 | 
						|
 | 
						|
You'll get a JSON response looking like this:
 | 
						|
 | 
						|
```json
 | 
						|
{
 | 
						|
    "id": "4fd3477b-eccf-4ee3-8f7d-68ad72261476",
 | 
						|
    "email": "king.arthur@camelot.bt",
 | 
						|
    "is_active": true,
 | 
						|
    "is_superuser": false
 | 
						|
}
 | 
						|
```
 | 
						|
 | 
						|
### 5.1. Update any user
 | 
						|
 | 
						|
We can now update the profile of any user. For example, we can promote it as superuser.
 | 
						|
 | 
						|
#### Request
 | 
						|
 | 
						|
=== "cURL"
 | 
						|
    ``` bash
 | 
						|
    curl \
 | 
						|
    -H "Content-Type: application/json" \
 | 
						|
    -H "Authorization: Bearer $TOKEN" \
 | 
						|
    -X PATCH \
 | 
						|
     -d "{\"is_superuser\": true}" \
 | 
						|
    http://localhost:8000/users/4fd3477b-eccf-4ee3-8f7d-68ad72261476
 | 
						|
    ```
 | 
						|
 | 
						|
=== "axios"
 | 
						|
    ```ts
 | 
						|
    axios.patch(
 | 
						|
        'http://localhost:8000/users/4fd3477b-eccf-4ee3-8f7d-68ad72261476',
 | 
						|
        {
 | 
						|
            is_superuser: true,
 | 
						|
        },
 | 
						|
        {
 | 
						|
            headers: {
 | 
						|
                'Authorization': `Bearer ${TOKEN}`,
 | 
						|
            },
 | 
						|
        },
 | 
						|
    )
 | 
						|
    .then((response) => console.log(response))
 | 
						|
    .catch((error) => console.log(error));
 | 
						|
    ```
 | 
						|
 | 
						|
#### Response
 | 
						|
 | 
						|
You'll get a JSON response looking like this:
 | 
						|
 | 
						|
```json
 | 
						|
{
 | 
						|
    "id": "4fd3477b-eccf-4ee3-8f7d-68ad72261476",
 | 
						|
    "email": "king.arthur@camelot.bt",
 | 
						|
    "is_active": true,
 | 
						|
    "is_superuser": true
 | 
						|
}
 | 
						|
```
 | 
						|
 | 
						|
### 5.2. Delete any user
 | 
						|
 | 
						|
Finally, we can delete a user.
 | 
						|
 | 
						|
#### Request
 | 
						|
 | 
						|
=== "cURL"
 | 
						|
    ``` bash
 | 
						|
    curl \
 | 
						|
    -H "Content-Type: application/json" \
 | 
						|
    -H "Authorization: Bearer $TOKEN" \
 | 
						|
    -X DELETE \
 | 
						|
    http://localhost:8000/users/4fd3477b-eccf-4ee3-8f7d-68ad72261476
 | 
						|
    ```
 | 
						|
 | 
						|
=== "axios"
 | 
						|
    ```ts
 | 
						|
    axios.delete(
 | 
						|
        'http://localhost:8000/users/4fd3477b-eccf-4ee3-8f7d-68ad72261476',
 | 
						|
        {
 | 
						|
            headers: {
 | 
						|
                'Authorization': `Bearer ${TOKEN}`,
 | 
						|
            },
 | 
						|
        },
 | 
						|
    )
 | 
						|
    .then((response) => console.log(response))
 | 
						|
    .catch((error) => console.log(error));
 | 
						|
    ```
 | 
						|
 | 
						|
#### Response
 | 
						|
 | 
						|
You'll get an empty response.
 | 
						|
 | 
						|
## 6. Logout
 | 
						|
 | 
						|
We can also end the session.
 | 
						|
 | 
						|
### Request
 | 
						|
 | 
						|
=== "cURL"
 | 
						|
    ``` bash
 | 
						|
    curl \
 | 
						|
    -H "Content-Type: application/json" \
 | 
						|
    -H "Cookie: fastapiusersauth=$TOKEN" \
 | 
						|
    -X POST \
 | 
						|
    http://localhost:8000/auth/cookie/logout
 | 
						|
    ```
 | 
						|
 | 
						|
=== "axios"
 | 
						|
    ```ts
 | 
						|
    axios.post('http://localhost:8000/auth/cookie/logout',
 | 
						|
        null,
 | 
						|
        {
 | 
						|
            headers: {
 | 
						|
                'Cookie': `fastapiusersauth=${TOKEN}`,
 | 
						|
            },
 | 
						|
        }
 | 
						|
    )
 | 
						|
    .then((response) => console.log(response))
 | 
						|
    .catch((error) => console.log(error));
 | 
						|
    ```
 | 
						|
 | 
						|
### Response
 | 
						|
 | 
						|
You'll get an empty response.
 | 
						|
 | 
						|
## Conclusion
 | 
						|
 | 
						|
That's it! You now have a good overview of how you can manage the users through the API. Be sure to check the [Routes](./routes.md) page to have all the details about each endpoints.
 |