mirror of
				https://github.com/fastapi-users/fastapi-users.git
				synced 2025-10-31 01:17:12 +08:00 
			
		
		
		
	 c4de66b81c
			
		
	
	c4de66b81c
	
	
	
		
			
			* 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.
 |