mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-04 22:13:36 +00:00
update base
This commit is contained in:
20
docs/docs/guides/integrate/login-ui/_logout.mdx
Normal file
20
docs/docs/guides/integrate/login-ui/_logout.mdx
Normal file
@@ -0,0 +1,20 @@
|
||||
When your user is done using your application and clicks on the logout button, you have to send a request to the terminate session endpoint.
|
||||
[Terminate Session Documentation](https://zitadel.com/docs/apis/resources/session_service/session-service-delete-session)
|
||||
|
||||
Send the session token in the body of the request.
|
||||
|
||||
### Request
|
||||
|
||||
```bash
|
||||
curl --request DELETE \
|
||||
--url https://$ZITADEL_DOMAIN/v2alpha/sessions/218480890961985793 \
|
||||
--header 'Accept: application/json' \
|
||||
--header 'Authorization: Bearer '"$TOKEN"''\
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"sessionToken": "blGKerGQPKv8jN21p6E9GB1B-vl6_EyKlvTd5UALu8-aQmjucgZxHSXJx3XMFTwT9_Y3VnbOo3gC_Q"
|
||||
}'
|
||||
```
|
||||
|
||||
Terminating a session means to delete it.
|
||||
If you try to read the session afterwards, you will get an error “Session does not exist”.
|
||||
80
docs/docs/guides/integrate/login-ui/_select-account.mdx
Normal file
80
docs/docs/guides/integrate/login-ui/_select-account.mdx
Normal file
@@ -0,0 +1,80 @@
|
||||
|
||||
If you want to build your own select account/account picker, you have to cache the session IDs.
|
||||
We recommend storing a list of the session Ids with the corresponding session token in a cookie.
|
||||
The list of session IDs can be sent in the “search sessions” request to get a detailed list of sessions for the account selection.
|
||||
|
||||
[Search Sessions Documentation](https://zitadel.com/docs/apis/resources/session_service/session-service-list-sessions)
|
||||
|
||||
### Request
|
||||
|
||||
```bash
|
||||
curl --request POST \
|
||||
--url https://$ZITADEL_DOMAIN/v2alpha/sessions/_search \
|
||||
--header 'Accept: application/json' \
|
||||
--header 'Authorization: Bearer '"$TOKEN"''\
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"query": {
|
||||
"offset": "0",
|
||||
"limit": 100,
|
||||
"asc": true
|
||||
},
|
||||
"queries": [
|
||||
{
|
||||
"idsQuery": {
|
||||
"ids": [
|
||||
"218380657934467329", "218480890961985793"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
### Response
|
||||
|
||||
```bash
|
||||
{
|
||||
"details": {
|
||||
"totalResult": "2",
|
||||
"processedSequence": "582",
|
||||
"timestamp": "2023-06-14T05:42:11.644220Z"
|
||||
},
|
||||
"sessions": [
|
||||
{
|
||||
"id": "218380657934467329",
|
||||
"creationDate": "2023-06-13T12:56:56.683629Z",
|
||||
"changeDate": "2023-06-13T12:56:56.724450Z",
|
||||
"sequence": "574",
|
||||
"factors": {
|
||||
"user": {
|
||||
"verifiedAt": "2023-06-13T12:56:55.440850Z",
|
||||
"id": "218380659823356328",
|
||||
"loginName": "minnie-mouse@fabi.zitadel.app",
|
||||
"displayName": "Minnie Mouse"
|
||||
},
|
||||
"password": {
|
||||
"verifiedAt": "2023-06-13T12:56:56.675359Z"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "218480890961985793",
|
||||
"creationDate": "2023-06-14T05:32:38.977954Z",
|
||||
"changeDate": "2023-06-14T05:42:11.631901Z",
|
||||
"sequence": "582",
|
||||
"factors": {
|
||||
"user": {
|
||||
"verifiedAt": "2023-06-14T05:32:38.972712Z",
|
||||
"id": "218380659823356328",
|
||||
"loginName": "minnie-mouse@fabi.zitadel.app",
|
||||
"displayName": "Minnie Mouse"
|
||||
},
|
||||
"password": {
|
||||
"verifiedAt": "2023-06-14T05:42:11.619484Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
209
docs/docs/guides/integrate/login-ui/external-login.mdx
Normal file
209
docs/docs/guides/integrate/login-ui/external-login.mdx
Normal file
@@ -0,0 +1,209 @@
|
||||
---
|
||||
title: Handle External Login
|
||||
sidebar_label: External Identity Provider
|
||||
---
|
||||
|
||||
## Flow
|
||||
|
||||
The prerequisite for adding an external login (social and enterprise) to your user account is a registered identity provider on your ZITADEL instance or the organization of the user.
|
||||
If you haven’t added a provider yet, have a look at the following guide first: [Identity Providers](https://zitadel.com/docs/guides/integrate/identity-providers)
|
||||
|
||||

|
||||
|
||||
## Start the Provider Flow
|
||||
|
||||
ZITADEL will handle as much as possible from the authentication flow with the external provider.
|
||||
This requires you to initiate the flow with your desired provider.
|
||||
|
||||
Send the following two URLs in the request body:
|
||||
1. SuccessURL: Page that should be shown when the login was successful
|
||||
2. ErrorURL: Page that should be shown when an error happens during the authentication
|
||||
|
||||
In the response, you will get an authentication URL of the provider you like.
|
||||
[Start Identity Provider Flow Documentation](https://zitadel.com/docs/apis/resources/user_service/user-service-start-identity-provider-flow)
|
||||
|
||||
### Request
|
||||
|
||||
```bash
|
||||
curl --request POST \
|
||||
--url https://$ZITADEL_DOMAIN/v2alpha/users/idps/$IDP_ID/start \
|
||||
--header 'Accept: application/json' \
|
||||
--header 'Authorization: Bearer '"$TOKEN"''\
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"successUrl": "https://custom.com/login/idp/success",
|
||||
"failureUrl": "https://custom.com/login/idp/fail"
|
||||
}'
|
||||
```
|
||||
|
||||
### Response
|
||||
|
||||
```bash
|
||||
{
|
||||
"details": {
|
||||
"sequence": "592",
|
||||
"changeDate": "2023-06-14T12:51:29.654819Z",
|
||||
"resourceOwner": "163840776835432705"
|
||||
},
|
||||
"authUrl": "https://accounts.google.com/o/oauth2/v2/auth?client_id=Test&prompt=select_account&redirect_uri=https%3A%2F%2F$ZITADEL_DOMAIN%2Fidps%2Fcallback&response_type=code&scope=openid+profile+email&state=218525066445455617"
|
||||
}
|
||||
```
|
||||
|
||||
## Call Provider
|
||||
|
||||
The next step is to call the auth URL you got in the response from the previous step.
|
||||
This will open up the login page of the given provider. In this guide, it is Google Login.
|
||||
|
||||
```bash
|
||||
https://accounts.google.com/o/oauth2/v2/auth?client_id=Test&prompt=select_account&redirect_uri=https%3A%2F%2F$ZITADEL_DOMAIN%2Fidps%2Fcallback&response_type=code&scope=openid+profile+email&state=218525066445455617
|
||||
```
|
||||
|
||||
After the user has successfully authenticated, a redirect to the ZITADEL backend /idps/callback will automatically be performed.
|
||||
|
||||
## Get Provider Information
|
||||
|
||||
ZITADEL will take the information of the provider. After this, a redirect will be made to either the success page in case of a successful login or to the error page in case of a failure will be performed. In the parameters, you will provide the intentID, a token, and optionally, if a user could be found, a user ID.
|
||||
|
||||
To get the information of the provider, make a request to ZITADEL.
|
||||
[Get Identity Provider Information Documentation](https://zitadel.com/docs/apis/resources/user_service/user-service-retrieve-identity-provider-information)
|
||||
|
||||
### Request
|
||||
```bash
|
||||
curl --request POST \
|
||||
--url https://$ZITADEL_DOMAIN/v2alpha/users/intents/$INTENT_ID/information \
|
||||
--header 'Accept: application/json' \
|
||||
--header 'Authorization: Bearer '"$TOKEN"''\
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"token": "k50WQmDaPIazQDJsyKaEPaQPwgsytxqgQ3K1ifQeQtAmeQ"
|
||||
}'
|
||||
```
|
||||
|
||||
### Response
|
||||
|
||||
```bash
|
||||
{
|
||||
"details": {
|
||||
"sequence": "599",
|
||||
"changeDate": "2023-06-15T06:44:26.039444Z",
|
||||
"resourceOwner": "163840776835432705"
|
||||
},
|
||||
"idpInformation": {
|
||||
"oauth": {
|
||||
"accessToken": "ya29.a0AWY7CknrOORopcJK2XX2fQXV9NQpp8JdkKYx-mQZNrR-wktWWhc3QsepT6kloSCgFPS9N0beEBlEYoY5oYUhfc7VlLHTQz5iECE386pyx5YmTueyeQ9GXk1dAw89gi8KRyjNlJApFsfLJaoiLIvKJLf23eAyXgaCgYKAUMSARESFQG1tDrpnTJ2su8BBO24zfmzgneARw0165",
|
||||
"idToken": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ijg1YmE5MzEzZmQ3YTdkNGFmYTg0ODg0YWJjYzg0MDMwMDQzNjMxODAiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhenAiOiIxODI5MDIwMjY1MDgtdW1taXQ3dHZjbHBnM2NxZmM4b2ljdGE1czI1aGtudWwuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJhdWQiOiIxODI5MDIwMjY1MDgtdW1taXQ3dHZjbHBnM2NxZmM4b2ljdGE1czI1aGtudWwuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMTEzOTI4MDU5NzU3MTU4NTY2MzciLCJoZCI6InJvb3RkLmNoIiwiZW1haWwiOiJmYWJpZW5uZUByb290ZC5jaCIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJhdF9oYXNoIjoidGN5X25JTkZHNnFhRTBZTWFsQzZGdyIsIm5hbWUiOiJGYWJpZW5uZSBCw7xobGVyIiwicGljdHVyZSI6Imh0dHBzOi8vbGgzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9hL0FBY0hUdGY5NzNRNk5IOEt6S1RNRVpFTFBVOWx4NDVXcFE5RlJCdXhGZFBiPXM5Ni1jIiwiZ2l2ZW5fbmFtZSI6IkZhYmllbm5lIiwiZmFtaWx5X25hbWUiOiJCw7xobGVyIiwibG9jYWxlIjoiZGUiLCJpYXQiOjE2ODY4MTE0NjUsImV4cCI6MTY4NjgxNTA2NX0.PwlAHRM44e8eYyHzdfotOrcq5GZc4D15mWvN3rGdoDmu2RRgb4T0nDgkY6AVq2vNJxPfbiB1jFtNP6dgX-OgLIxNXg_tJJhwFh-eFPA37cIiv1CEcgEC-q1zXFIa3HrwHLreeU6i7C9JkDrKpkS-AKat1krf27QXxrxHLrWehi5F2l1OZuAKFWYaYmJOd0sVTDBA2o5SDcAiQs_D4-Q-kSl5f0gh607YVHLv7zjyfHtAOs7xPEkNEUVcqGBke2Zy9kAYIgiMriNxLA2EDxFtSyWnf-bCXKnuVX2hwEY0T0lUPrOAVkz7MEOKiacE2xAOczoQvl-wECU0UofLi8XZqg"
|
||||
},
|
||||
"idpId": "218528353504723201",
|
||||
"rawInformation": {
|
||||
"User": {
|
||||
"email": "fabienne@rootd.ch",
|
||||
"email_verified": true,
|
||||
"family_name": "Bühler",
|
||||
"given_name": "Fabienne",
|
||||
"hd": "rootd.ch",
|
||||
"locale": "de",
|
||||
"name": "Fabienne Bühler",
|
||||
"picture": "https://lh3.googleusercontent.com/a/AAcKTtf973Q6NH8KzKTMEZELPU9lx45WpQ9FRBuxFdPb=s96-c",
|
||||
"sub": "111392805975715856637"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Handle Provider Information
|
||||
After successfully authenticating using your identity provider, you have three possible options.
|
||||
1. Login
|
||||
2. Register user
|
||||
3. Add social login to existing user
|
||||
|
||||
### Login
|
||||
|
||||
If you did get a user ID in the parameters when calling your success page, you know that a user is already linked with the used identity provider and you are ready to perform the login.
|
||||
Create a new session and include the intent ID and the token in the checks.
|
||||
This check requires that the previous step ended on the successful page and didn't’t result in an error.
|
||||
|
||||
#### Request
|
||||
```bash
|
||||
curl --request POST \
|
||||
--url https://$ZITADEL_DOMAIN/v2alpha/sessions \
|
||||
--header 'Accept: application/json' \
|
||||
--header 'Authorization: Bearer '"$TOKEN"''\
|
||||
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"checks": {
|
||||
"user": {
|
||||
"userId": "218662596918640897"
|
||||
},
|
||||
"intent": {
|
||||
"intentId": "219647325729980673",
|
||||
"token": "k86ihn-VLMMUGKy1q1b5i_foECspKYqei1l4mS8LT7Xzjw"
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Register
|
||||
|
||||
If you didn't get a user ID in the parameters of your success page, you know that there is no existing user in ZITADEL with that provider, and you can register a new user or link it to an existing account (read the next section).
|
||||
|
||||
Fill the IdP links in the create user request to add a user with an external login provider.
|
||||
The idpId is the ID of the provider in ZITADEL, the idpExternalId is the ID of the user in the external identity provider; usually, this is sent in the “sub”.
|
||||
The display name is used to list the linkings on the users.
|
||||
|
||||
[Create User API Documentation](https://zitadel.com/docs/apis/resources/user_service/user-service-add-human-user)
|
||||
|
||||
#### Request
|
||||
```bash
|
||||
curl --request POST \
|
||||
--url https://$ZITADEL_DOMAIN/v2alpha/users/human \
|
||||
--header 'Accept: application/json' \
|
||||
--header 'Authorization: Bearer '"$TOKEN"''\
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"username": "minni-mouse@mouse.com",
|
||||
"profile": {
|
||||
"firstName": "Minnie",
|
||||
"lastName": "Mouse",
|
||||
"nickName": "Mini",
|
||||
"displayName": "Minnie Mouse",
|
||||
"preferredLanguage": "en",
|
||||
"gender": "GENDER_FEMALE"
|
||||
},
|
||||
"email": {
|
||||
"email": "minni-mouse@mouse.com",
|
||||
"isVerified": true
|
||||
},
|
||||
"idpLinks": [
|
||||
{
|
||||
"idpId": "218528353504723201",
|
||||
"idpExternalId": "111392805975715856637",
|
||||
"displayName": "Minnie Mouse"
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
### Add External Login to Existing User
|
||||
|
||||
If you didn't get a user ID in the parameters to your success page, you know that there is no existing user in ZITADEL with that provider and you can register a new user (read previous section), or link it to an existing account.
|
||||
|
||||
If you want to link/connect to an existing account you can perform the add identity provider link request.
|
||||
[Add IDP Link to existing user documentation](https://zitadel.com/docs/apis/resources/user_service/user-service-add-idp-link)
|
||||
|
||||
#### Request
|
||||
```bash
|
||||
curl --request POST \
|
||||
--url https://$ZITADEL_DOMAIN/v2alpha/users/users/218385419895570689/links \
|
||||
--header 'Accept: application/json' \
|
||||
--header 'Authorization: Bearer '"$TOKEN"''\
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"idpLink": {
|
||||
"idpId": "218528353504723201",
|
||||
"idpExternalId": "1113928059757158566371",
|
||||
"displayName": "Minnie Mouse"
|
||||
}
|
||||
}'
|
||||
```
|
||||
7
docs/docs/guides/integrate/login-ui/logout.mdx
Normal file
7
docs/docs/guides/integrate/login-ui/logout.mdx
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
title: Logout
|
||||
---
|
||||
|
||||
import Logout from './_logout.mdx';
|
||||
|
||||
<Logout/>
|
||||
26
docs/docs/guides/integrate/login-ui/oidc-standard.mdx
Normal file
26
docs/docs/guides/integrate/login-ui/oidc-standard.mdx
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
title: OIDC Standard
|
||||
---
|
||||
|
||||
:::info
|
||||
Not yet implemented, but should give you a general impression of how it will work
|
||||
Subscribe to the following issue: https://github.com/orgs/zitadel/projects/2/views/1?filterQuery=oidc&pane=issue&itemId=23181369
|
||||
:::
|
||||
|
||||
To build your own login ui for your own application it is not necessary to have the OIDC standard included or any additional work that has to be done.
|
||||
However, it might make sense, if you want to connect your login to different applications especially if they are not in your control and they rely on the standard.
|
||||
|
||||
The following flow shows you the different components you need to enable OIDC for your login.
|
||||

|
||||
|
||||
1. Your application makes an authorization request to your login UI
|
||||
2. The login UI takes the requests and sends them to the ZITADEL API. In the request to the ZITADEL API, a header to authenticate your client is needed.
|
||||
3. The ZITADEL API parses the request and does what it needs to interpret certain parameters (e.g., organization scope, etc.)
|
||||
4. Redirect to a predefined, relative URL of the login UI that includes the authrequest ID
|
||||
5. Request to ZITADEL API to get all the information from the auth request
|
||||
6. Create and update the session till the login flow is complete and the user is authenticated. Make sure to include the auth Request ID in the session
|
||||
7. Read the callback URL from the ZITADEL API
|
||||
8. Redirect to your application with the callback URL you got in the previous request
|
||||
9. All OIDC-specific endpoints have to be accepted in the Login UI and should be proxied and sent to the ZITADEL API
|
||||
|
||||
|
||||
106
docs/docs/guides/integrate/login-ui/password-reset.mdx
Normal file
106
docs/docs/guides/integrate/login-ui/password-reset.mdx
Normal file
@@ -0,0 +1,106 @@
|
||||
---
|
||||
title: Password Reset/Change
|
||||
---
|
||||
|
||||
When your user is on the password screen and has forgotten his password you will probably want him to be able to reset by himself.
|
||||
|
||||
## Flow
|
||||
|
||||

|
||||
|
||||
## Request Password Reset
|
||||
|
||||
First you will have to make a request, to ask for a password reset.
|
||||
The goal is to send the user a verification code, which he can use to verify the password reset request.
|
||||
|
||||
There are two possible ways: You can either let ZITADEL send the notification with the verification code, or you can ask ZITADEL for returning the code and send the email by yourself.
|
||||
|
||||
### ZITADEL sends the verification message
|
||||
|
||||
When you want ZITADEL to send the verification code you can define the notification channel.
|
||||
Per default the verification code will be sent to the email address of the user.
|
||||
|
||||
Make sure to also include the URL Template to customize the reset link in the email sent to the user.
|
||||
|
||||
|
||||
### Request
|
||||
|
||||
```bash
|
||||
curl --request POST \
|
||||
--url https://$ZITADEL_DOMAIN/v2alpha/users/$USER_ID/password_reset \
|
||||
--header 'Accept: application/json' \
|
||||
--header 'Authorization: Bearer '"$TOKEN"'' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"sendLink": {
|
||||
"notificationType": "NOTIFICATION_TYPE_Email",
|
||||
"urlTemplate": "https://example.com/password/changey?userID={{.UserID}}&code={{.Code}}&orgID={{.OrgID}}"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### ZITADEL returns the code
|
||||
|
||||
Send the request with asking for the return Code in the body of the request.
|
||||
|
||||
#### Request
|
||||
```bash
|
||||
curl --request POST \
|
||||
--url https://$ZITADEL_DOMAIN/v2alpha/users/$USER_ID/password_reset \
|
||||
--header 'Accept: application/json' \
|
||||
--header 'Authorization: Bearer '"$TOKEN"'' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"returnCode": {}
|
||||
}'
|
||||
```
|
||||
|
||||
#### Response
|
||||
|
||||
You will get the verification code in the response:
|
||||
```bash
|
||||
{
|
||||
"details": {
|
||||
"sequence": "625",
|
||||
"changeDate": "2023-06-27T15:02:10.321773Z",
|
||||
"resourceOwner": "163840776835432705"
|
||||
},
|
||||
"verificationCode": "IBJMUC"
|
||||
}
|
||||
```
|
||||
|
||||
## Send Verification Code
|
||||
|
||||
The verification code is generated and ZITADEL has sent it with the defined channel (email or sms) to your users.
|
||||
If you have chosen to get the code back in the response, you should now send the code to your user.
|
||||
|
||||
## Change Password
|
||||
|
||||
The next screen should allow the user to enter the verification code and a new password.
|
||||
From a user experience perspective it is nice to prefill the verification code, so the user doesn't have to do manually.
|
||||
|
||||
As soon as the user has typed the new password, you can send the change password request.
|
||||
The change password request allows you to set a new password for the user.
|
||||
|
||||
:::note
|
||||
This request can be used in the password reset flow as well as to let your user change the password manually.
|
||||
In this case it requires additionally the current password instead of the verification code.
|
||||
:::
|
||||
|
||||
|
||||
### Request
|
||||
|
||||
```bash
|
||||
curl --request POST \
|
||||
--url https://$ZITADEL_DOMAIN/v2alpha/users/$USER_ID/password \
|
||||
--header 'Accept: application/json' \
|
||||
--header 'Authorization: Bearer '"$TOKEN"'' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"newPassword": {
|
||||
"password": "Secr3tP4ssw0rd!",
|
||||
"changeRequired": false
|
||||
},
|
||||
"verificationCode": "48CDAP"
|
||||
}'
|
||||
```
|
||||
7
docs/docs/guides/integrate/login-ui/select-account.mdx
Normal file
7
docs/docs/guides/integrate/login-ui/select-account.mdx
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
title: Select Account
|
||||
---
|
||||
|
||||
import SelectAccount from './_select-account.mdx';
|
||||
|
||||
<SelectAccount/>
|
||||
236
docs/docs/guides/integrate/login-ui/username-password.mdx
Normal file
236
docs/docs/guides/integrate/login-ui/username-password.mdx
Normal file
@@ -0,0 +1,236 @@
|
||||
---
|
||||
title: Register and Login User with Password
|
||||
sidebar_label: Username and Password
|
||||
---
|
||||
|
||||
## Flow
|
||||
|
||||

|
||||
|
||||
## Register
|
||||
|
||||
First, we create a new user with a username and password. In the example below we add a user with profile data, a verified email address, and a password.
|
||||
[Create User Documentation](/apis/resources/user_service/user-service-add-human-user)
|
||||
|
||||
### Request
|
||||
|
||||
```bash
|
||||
curl --request POST \
|
||||
--url https://$ZITADEL_DOMAIN/v2alpha/users/human \
|
||||
--header 'Accept: application/json' \
|
||||
--header 'Authorization: Bearer '"$TOKEN"'' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"userId": "d654e6ba-70a3-48ef-a95d-37c8d8a7901a",
|
||||
"username": "minnie-mouse",
|
||||
"profile": {
|
||||
"firstName": "Minnie",
|
||||
"lastName": "Mouse",
|
||||
"nickName": "Mini",
|
||||
"displayName": "Minnie Mouse",
|
||||
"preferredLanguage": "en",
|
||||
"gender": "GENDER_FEMALE"
|
||||
},
|
||||
"email": {
|
||||
"email": "mini@mouse.com",
|
||||
"isVerified": true
|
||||
},
|
||||
"metadata": [
|
||||
{
|
||||
"key": "my-key",
|
||||
"value": "VGhpcyBpcyBteSB0ZXN0IHZhbHVl"
|
||||
}
|
||||
],
|
||||
"password": {
|
||||
"password": "Secr3tP4ssw0rd!",
|
||||
"changeRequired": false
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Response
|
||||
|
||||
```bash
|
||||
{
|
||||
"userId": "d654e6ba-70a3-48ef-a95d-37c8d8a7901a",
|
||||
"details": {
|
||||
"sequence": "570",
|
||||
"changeDate": "2023-06-13T12:44:36.967851Z",
|
||||
"resourceOwner": "163840776835432705"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you want the user to verify the email address you can either choose that ZITADEL sends a verification email to the user by adding a urlTemplate into the sendCode, or ask for a return code to send your own emails.
|
||||
|
||||
Send Email by ZITADEL:
|
||||
|
||||
```bash
|
||||
"sendCode": {
|
||||
"urlTemplate": "https://example.com/email/verify?userID={{.UserID}}&code={{.Code}}&orgID={{.OrgID}}"
|
||||
},
|
||||
```
|
||||
|
||||
Return Code:
|
||||
```bash
|
||||
"email": {
|
||||
"email": "mini@mouse.com",
|
||||
"returnCode": {}
|
||||
},
|
||||
```
|
||||
|
||||
To check what is allowed on your instance, call the settings service for more information.
|
||||
The following requests can be useful for registration:
|
||||
- [Get Login Settings](https://zitadel.com/docs/apis/resources/settings_service/settings-service-get-login-settings) To find out which authentication possibilities are enabled (password, identity provider, etc.)
|
||||
- [Get Password Complexity Settings](https://zitadel.com/docs/apis/resources/settings_service/settings-service-get-password-complexity-settings) to find out how the password should look like (length, characters, etc.)
|
||||
|
||||
## Create Session with User Check
|
||||
|
||||
After you have created a new user, you can redirect him to your login screen.
|
||||
You can either create a new empty session as soon as the first login screen is shown or update it with each piece of information you get throughout the process.
|
||||
Or you can create a new session with the first credentials a user enters.
|
||||
In the following example, we assume that the login flow asks for the username in the first step, and in the second for the password.
|
||||
In API requests, this means creating a new session with a username and updating it with the password.
|
||||
If you already have the userId from a previous register, you can send it directly to skip the username and show the password screen directly.
|
||||
The create and update session endpoints will always return a session ID and an opaque session token.
|
||||
If you do not rely on the OIDC standard you can directly use the token.
|
||||
Send it to the Get Session Endpoint to find out how the user has authenticated.
|
||||
|
||||
- [Create new session Documentation](https://zitadel.com/docs/apis/resources/session_service/session-service-create-session)
|
||||
- [Update an existing session Documentation](https://zitadel.com/docs/apis/resources/session_service/session-service-set-session)
|
||||
- [Get Session Documentation](https://zitadel.com/docs/apis/resources/session_service/session-service-get-session)
|
||||
|
||||
### Request
|
||||
|
||||
```bash
|
||||
curl --request POST \
|
||||
--url https://$ZITADEL_DOMAIN/v2alpha/sessions \
|
||||
--header 'Accept: application/json' \
|
||||
--header 'Authorization: Bearer '"$TOKEN"'' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"checks": {
|
||||
"user": {
|
||||
"loginName": "minnie-mouse@fabi.zitadel.app"
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Response
|
||||
|
||||
```bash
|
||||
{
|
||||
"details": {
|
||||
"sequence": "580",
|
||||
"changeDate": "2023-06-14T05:32:39.007096Z",
|
||||
"resourceOwner": "163840776835432705"
|
||||
},
|
||||
"sessionId": "218480890961985793",
|
||||
"sessionToken": "yMDi6uVPJAcphbbz0LaxC07ihWkNTe7m0Xqch8SzfM5Cz3HSIQIDZ65x1f5Qal0jxz0MEyo-_zYcUg"
|
||||
}
|
||||
```
|
||||
|
||||
### Session State
|
||||
|
||||
If you read the newly created session, it will look like the following.
|
||||
You can see the creation and change date.
|
||||
In the factors, you will see all the checks that have been made.
|
||||
In this case, the user has been checked.
|
||||
|
||||
```bash
|
||||
{
|
||||
"session": {
|
||||
"id": "218480890961985793",
|
||||
"creationDate": "2023-06-14T05:32:38.977954Z",
|
||||
"changeDate": "2023-06-14T05:32:39.007096Z",
|
||||
"sequence": "580",
|
||||
"factors": {
|
||||
"user": {
|
||||
"verifiedAt": "2023-06-14T05:32:38.972712Z",
|
||||
"id": "d654e6ba-70a3-48ef-a95d-37c8d8a7901a",
|
||||
"loginName": "minnie-mouse@fabi.zitadel.app",
|
||||
"displayName": "Minnie Mouse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Update Session with Password
|
||||
|
||||
Your session already has a username check.
|
||||
The next step is to check the password.
|
||||
To update an existing session, add the session ID to the URL and the session token you got in the previous step to the request body.
|
||||
|
||||
### Request
|
||||
|
||||
```bash
|
||||
curl --request PATCH \
|
||||
--url https://$ZITADEL_DOMAIN/v2alpha/sessions/$SESSION_ID \
|
||||
--header 'Accept: application/json' \
|
||||
--header 'Authorization: Bearer '"$TOKEN"''\
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"sessionToken": "yMDi6uVPJAcphbbz0LaxC07ihWkNTe7m0Xqch8SzfM5Cz3HSIQIDZ65x1f5Qal0jxz0MEyo-_zYcUg",
|
||||
"checks": {
|
||||
"password": {
|
||||
"password": "Secr3tP4ssw0rd!"
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Response
|
||||
|
||||
The response of the create and update session token looks the same.
|
||||
Make sure to always use the session token of the last response you got, as the values may be updated.
|
||||
|
||||
```bash
|
||||
{
|
||||
"details": {
|
||||
"sequence": "582",
|
||||
"changeDate": "2023-06-14T05:42:11.631901Z",
|
||||
"resourceOwner": "163840776835432705"
|
||||
},
|
||||
"sessionToken": "blGKerGQPKv8jN21p6E9GB1B-vl6_EyKlvTd5UALu8-aQmjucgZxHSXJx3XMFTwT9_Y3VnbOo3gC_Q"
|
||||
}
|
||||
```
|
||||
|
||||
### Session State
|
||||
If you read your session after the password check, you will see that the check has been added to the factors with the verification date.
|
||||
|
||||
```bash
|
||||
{
|
||||
"session": {
|
||||
"id": "218480890961985793",
|
||||
"creationDate": "2023-06-14T05:32:38.977954Z",
|
||||
"changeDate": "2023-06-14T05:42:11.631901Z",
|
||||
"sequence": "582",
|
||||
"factors": {
|
||||
"user": {
|
||||
"verifiedAt": "2023-06-14T05:32:38.972712Z",
|
||||
"id": "d654e6ba-70a3-48ef-a95d-37c8d8a7901a",
|
||||
"loginName": "minnie-mouse@fabi.zitadel.app",
|
||||
"displayName": "Minnie Mouse"
|
||||
},
|
||||
"password": {
|
||||
"verifiedAt": "2023-06-14T05:42:11.619484Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## List the Sessions (Account Chooser)
|
||||
|
||||
import SelectAccount from './_select-account.mdx';
|
||||
|
||||
<SelectAccount/>
|
||||
|
||||
## Logout User
|
||||
|
||||
import Logout from './_logout.mdx';
|
||||
|
||||
<Logout/>
|
||||
@@ -5,158 +5,57 @@ title: User Metadata
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
In this guide you will learn how to manually create the necessary requests to authenticate and request a user's metadata from ZITADEL.
|
||||
This guide shows you how to request metadata from a user.
|
||||
ZITADEL offers multiple methods to retrieve metadata.
|
||||
Pick the one that works best for your solution.
|
||||
|
||||
Typical examples for user metadata include:
|
||||
## Use cases for metadata
|
||||
|
||||
Typical use cases for user metadata include:
|
||||
|
||||
- Link the user to an internal identifier (eg, userId, contract number, etc.)
|
||||
- Save custom user data when registering a user
|
||||
- Route upstream traffic based on user attributes
|
||||
|
||||
## Prerequisites
|
||||
## Before you start
|
||||
|
||||
### Create a new client
|
||||
Before you start you need to add some metadata to an existing user.
|
||||
You can do so by using [Console](../console/users) or [setting user metadata](/docs/apis/resources/mgmt/management-service-set-user-metadata) through the management API.
|
||||
|
||||
- Create a new [web application](../console/applications#web)
|
||||
- Use Code-Flow
|
||||
- In this example we will use `http://localhost` as redirect url
|
||||
- Make sure to note the client secret
|
||||
Most of the methods below require you to login with the correct user while setting some scopes.
|
||||
Make sure you pick the right user when logging into the test application.
|
||||
Use the [OIDC authentication request playground](/docs/apis/openidoauth/authrequest) or the configuration of an [example client](/docs/examples/introduction) to set the required scopes and receive a valid access token.
|
||||
|
||||
### Add metadata to a user
|
||||
|
||||
- [Add metadata](/guides/manage/customize/user-metadata) to a user
|
||||
- Make sure you will use this user to login during later steps
|
||||
|
||||
## Requesting a token
|
||||
|
||||
:::info
|
||||
In this guide we will manually request a token from ZITADEL for demonstration purposes. You will likely use a client library for the OpenID Authentication.
|
||||
:::info Getting a token
|
||||
In case you want to test out different settings configure an application with code flow (PKCE).
|
||||
Grab the code from the url parameter after a successful login and exchange the code for tokens by calling the [token endpoint](/docs/apis/openidoauth/endpoints#token_endpoint).
|
||||
You will find more information in our guides on how to [authenticate users](/docs/guides/integrate/login-users).
|
||||
:::
|
||||
|
||||
### Set environment variables
|
||||
## Use tokens to get user metadata
|
||||
|
||||
We will use some information throughout this guide. Set the required environment variables as follows. Make sure to replace the values with your information.
|
||||
Use one of these methods to get the metadata for the currently logged in user.
|
||||
|
||||
```bash
|
||||
export CLIENT_SECRET=QCiMffalakI...zpT0vuOsSkVk1ne \
|
||||
export CLIENT_ID="16604...@docs-claims" \
|
||||
export REDIRECT_URI="http://localhost" \
|
||||
export ZITADEL_DOMAIN="https://...asd.zitadel.cloud"
|
||||
```
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="go" label="Go" default>
|
||||
|
||||
Grab zitadel-tools to create the [required string](/apis/openidoauth/authn-methods#client-secret-basic) for Basic authentication:
|
||||
|
||||
```bash
|
||||
git clone git@github.com:zitadel/zitadel-tools.git
|
||||
cd zitadel-tools/cmd/basicauth
|
||||
export BASIC_AUTH="$(go run basicauth.go -id $CLIENT_ID -secret $CLIENT_SECRET)"
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="python" label="Python">
|
||||
|
||||
```python
|
||||
import base64
|
||||
import urllib.parse
|
||||
import os
|
||||
|
||||
clientId = os.environ.get("CLIENT_ID")
|
||||
clientSecret = os.environ.get("CLIENT_SECRET")
|
||||
|
||||
escaped = safe_string = urllib.parse.quote_plus(clientId) + ":" + urllib.parse.quote_plus(clientSecret)
|
||||
message_bytes = escaped.encode('ascii')
|
||||
base64_bytes = base64.b64encode(message_bytes)
|
||||
base64_message = base64_bytes.decode('ascii')
|
||||
|
||||
print(base64_message)
|
||||
```
|
||||
|
||||
Export the result to the environment variable `BASIC_AUTH`.
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="js" label="Javascript" default>
|
||||
|
||||
```javascript
|
||||
esc = encodeURIComponent(process.env.CLIENT_ID) + ":" + encodeURIComponent(process.env.CLIENT_SECRET)
|
||||
enc = btoa(esc)
|
||||
console.log(enc)
|
||||
```
|
||||
|
||||
Export the result to the environment variable `BASIC_AUTH`.
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="manually" label="Manually">
|
||||
|
||||
You need to create a string as described [here](/apis/openidoauth/authn-methods#client-secret-basic).
|
||||
|
||||
Use a programming language of your choice or manually create the strings with online tools (don't use these secrets for production) like:
|
||||
|
||||
- https://www.urlencoder.org/
|
||||
- https://www.base64encode.org/
|
||||
|
||||
Export the result to the environment variable `BASIC_AUTH`.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Create Auth Request
|
||||
|
||||
You need to create a valid auth request, including the reserved scope `urn:zitadel:iam:user:metadata`. Please refer to our API documentation for more information about [reserved scopes](/apis/openidoauth/scopes#reserved-scopes) or try it out in our [OIDC Authrequest Playground](/apis/openidoauth/authrequest?scope=openid%20email%20profile%20urn%3Azitadel%3Aiam%3Auser%3Ametadata).
|
||||
|
||||
Login with the user to which you have added the metadata. After the login you will be redirected.
|
||||
|
||||
Grab the code paramter from the url (disregard the &code= parameter) and export the code as environment variable:
|
||||
|
||||
```bash
|
||||
export AUTH_CODE="Y6nWsgR5WB...zUtFqSp5Xw"
|
||||
```
|
||||
|
||||
### Token Request
|
||||
|
||||
```bash
|
||||
curl --request POST \
|
||||
--url "${ZITADEL_DOMAIN}/oauth/v2/token" \
|
||||
--header "Accept: application/json" \
|
||||
--header "Authorization: Basic ${BASIC_AUTH}" \
|
||||
--header 'Content-Type: application/x-www-form-urlencoded' \
|
||||
--data grant_type=authorization_code \
|
||||
--data-urlencode "code=$AUTH_CODE" \
|
||||
--data-urlencode "redirect_uri=$REDIRECT_URI"
|
||||
```
|
||||
|
||||
The result will give you something like:
|
||||
|
||||
```json
|
||||
{
|
||||
"access_token":"jZuRixKQTVecEjKqw...kc3G4",
|
||||
"token_type":"Bearer",
|
||||
"expires_in":43199,
|
||||
"id_token":"ey...Ww"
|
||||
}
|
||||
```
|
||||
|
||||
Grab the access_token value and export as an environment variable:
|
||||
|
||||
```bash
|
||||
export ACCESS_TOKEN="jZuRixKQTVecEjKqw...kc3G4"
|
||||
```
|
||||
In case you want to manage metadata for other users than the currently logged in user, then you must use the [management service](#manage-user-metadata-through-the-management-api).
|
||||
|
||||
### Request metadata from userinfo endpoint
|
||||
|
||||
With the access token we can make a request to the userinfo endpoint to get the user's metadata. This method is the preferred method to retrieve a user's information in combination with opaque tokens, to insure that the token is valid.
|
||||
With the access token we can make a request to the [userinfo endpoint](/docs/apis/openidoauth/endpoints#introspection_endpoint) to get the user's metadata.
|
||||
This method is the preferred method to retrieve a user's information in combination with opaque tokens, to insure that the token is valid.
|
||||
|
||||
You must pass the [reserved scope](/docs/apis/openidoauth/scopes#reserved-scopes) `urn:zitadel:iam:user:metadata` in your authentication request.
|
||||
If you don't include this scope the response will contain user data, but not the metadata object.
|
||||
|
||||
Request the user information by calling the [userinfo endpoint](/docs/apis/openidoauth/endpoints#introspection_endpoint):
|
||||
|
||||
```bash
|
||||
curl --request GET \
|
||||
--url "${ZITADEL_DOMAIN}/oidc/v1/userinfo" \
|
||||
--url "https://$ZITADEL_DOMAIN/oidc/v1/userinfo" \
|
||||
--header "Authorization: Bearer $ACCESS_TOKEN"
|
||||
```
|
||||
|
||||
Replace `$ACCESS_TOKEN` with your user's access token.
|
||||
|
||||
The response will look something like this
|
||||
|
||||
```json
|
||||
@@ -178,15 +77,19 @@ The response will look something like this
|
||||
}
|
||||
```
|
||||
|
||||
You can grab the metadata from the reserved claim `"urn:zitadel:iam:user:metadata"` as key-value pairs. Note that the values are base64 encoded. So the value `MTIzNA` decodes to `1234`.
|
||||
You can grab the metadata from the reserved claim `"urn:zitadel:iam:user:metadata"` as key-value pairs.
|
||||
Note that the values are base64 encoded.
|
||||
So the value `MTIzNA` decodes to `1234`.
|
||||
|
||||
### Send metadata inside the ID token (optional)
|
||||
### Send metadata inside the ID token
|
||||
|
||||
Check "User Info inside ID Token" in the configuration of your application.
|
||||
You might want to include metadata directly into the ID Token.
|
||||
For that you need to enable "User Info inside ID Token" in your application's settings.
|
||||
|
||||

|
||||
|
||||
Now request a new token from ZITADEL.
|
||||
Now request a new token from ZITADEL by logging in with the user that has metadata attached.
|
||||
Make sure you log into the correct client/application where you enabled the settings.
|
||||
|
||||
The result will give you something like:
|
||||
|
||||
@@ -199,4 +102,129 @@ The result will give you something like:
|
||||
}
|
||||
```
|
||||
|
||||
Grab the id_token and inspect the contents of the token at [jwt.io](https://jwt.io/). You should get the same info in the ID token as when requested from the user endpoint.
|
||||
When you decode the value of `id_token`, then the response will include the metadata claim:
|
||||
|
||||
```json
|
||||
{
|
||||
"amr": [
|
||||
"password",
|
||||
"pwd",
|
||||
"mfa",
|
||||
"otp"
|
||||
],
|
||||
"at_hash": "lGIblkTr8faHz2zd0oTddA",
|
||||
"aud": [
|
||||
"170086824411201793@portal",
|
||||
"209806276543185153@portal",
|
||||
"170086774599581953"
|
||||
],
|
||||
"auth_time": 1687418556,
|
||||
"azp": "170086824411201793@portal",
|
||||
"c_hash": "dA3wre4ytCJCn11f7cIm0A",
|
||||
"client_id": "1700...1793@portal",
|
||||
"email": "road.runner@zitadel.com",
|
||||
"email_verified": true,
|
||||
"exp": 1687422272,
|
||||
"family_name": "Runner",
|
||||
"given_name": "Road",
|
||||
"iat": 1687418672,
|
||||
"iss": "https://...-abcd.zitadel.cloud",
|
||||
"locale": null,
|
||||
"name": "Road Runner",
|
||||
"preferred_username": "road.runner@...-abcd.zitadel.cloud",
|
||||
"sub": "170848145649959169",
|
||||
"updated_at": 1658329554,
|
||||
//highlight-start
|
||||
"urn:zitadel:iam:user:metadata": {
|
||||
"ContractNumber": "MTIzNA"
|
||||
}
|
||||
//highlight-end
|
||||
}
|
||||
```
|
||||
|
||||
Note that the values are base64 encoded.
|
||||
So the value `MTIzNA` decodes to `1234`.
|
||||
|
||||
:::info decoding the jwt token
|
||||
Use a website like [jwt.io](https://jwt.io/) to decode the token.
|
||||
With jq installed you can also use `jq -R 'split(".") | .[1] | @base64d | fromjson' <<< $ID_TOKEN`
|
||||
:::
|
||||
|
||||
### Request metadata from authentication API
|
||||
|
||||
You can use the authentication service to request and search for the user's metadata.
|
||||
|
||||
The introspection endpoint and the token endpoint in the examples above do not require a special scope to access.
|
||||
Yet when accessing the authentication service, you need to pass the [reserved scope](/docs/apis/openidoauth/scopes#reserved-scopes) `urn:zitadel:iam:org:project:id:zitadel:aud` along with the authentication request.
|
||||
This scope allows the user to access ZITADEL's APIs, specifically the authentication API that we need for this method.
|
||||
Use the [OIDC authentication request playground](/docs/apis/openidoauth/authrequest) or the configuration of an [example client](/docs/examples/introduction) to set the required scopes and receive a valid access token.
|
||||
|
||||
:::note Invalid audience
|
||||
If you get the error "invalid audience (APP-Zxfako)", then you need to add the reserved scope `urn:zitadel:iam:org:project:id:zitadel:aud` to your authentication request.
|
||||
:::
|
||||
|
||||
You can request the user's metadata with the [List My Metadata](/docs/apis/resources/auth/auth-service-list-my-metadata) method:
|
||||
|
||||
```bash
|
||||
curl -L -X POST "https://$ZITADEL_DOMAIN/auth/v1/users/me/metadata/_search" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H 'Accept: application/json' \
|
||||
-H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||
--data-raw '{
|
||||
"query": {
|
||||
"offset": "0",
|
||||
"limit": 100,
|
||||
"asc": true
|
||||
},
|
||||
"queries": [
|
||||
{
|
||||
"keyQuery": {
|
||||
"key": "$METADATA_KEY",
|
||||
"method": "TEXT_QUERY_METHOD_EQUALS"
|
||||
}
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
Replace `$ACCESS_TOKEN` with your user's access token.
|
||||
Replace `$ZITADEL_DOMAIN` with your ZITADEL instance's url.
|
||||
Replace `$METADATA_KEY` with they key you want to search for (f.e. "ContractNumber")
|
||||
|
||||
:::info Get all metadata
|
||||
You can omit the queries array to retrieve all metadata key-value pairs.
|
||||
:::
|
||||
|
||||
An example response for your search looks like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"details":{
|
||||
"totalResult":"1",
|
||||
"processedSequence":"2935",
|
||||
"viewTimestamp":"2023-06-21T16:01:52.829838Z"
|
||||
},
|
||||
"result":[
|
||||
{
|
||||
"details":{
|
||||
"sequence":"409",
|
||||
"creationDate":"2022-08-04T09:09:06.259324Z",
|
||||
"changeDate":"2022-08-04T09:09:06.259324Z",
|
||||
"resourceOwner":"170086363054473473"
|
||||
},
|
||||
"key":"ContractNumber",
|
||||
"value":"MTIzNA"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Manage user metadata through the management API
|
||||
|
||||
The previous methods allowed you to retrieve metadata only for the `sub` in the access token.
|
||||
In case you want to get the metadata for another user, you need to use the management service.
|
||||
The user that calls the management service must have [manager permissions](/docs/guides/manage/console/managers).
|
||||
A user can be either a human user or a service user.
|
||||
|
||||
You can get [metadata of a user filtered by your query](/docs/apis/resources/mgmt/management-service-list-user-metadata) or [get a metadata object from a user by a specific key](/docs/apis/resources/mgmt/management-service-get-user-metadata).
|
||||
The management service allows you to set and delete metadata, see the [API documentation for users](/docs/category/apis/resources/mgmt/users).
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
title: Frontend and API communication
|
||||
---
|
||||
|
||||
This guide contains a use case and ZITADEL integration.
|
||||
|
||||
In a typical web application architecture, the front-end and back-end communicate to exchange data and provide functionality to users. Let's consider a use case where a front-end application needs to communicate with a back-end API using secure authentication and authorization. Let’s explore how ZITADEL can be used to add front-end login and facilitate this communication.
|
||||
|
||||
Single-Page Applications (SPAs) are web applications that run entirely in the browser, without a back-end server. In ZITADEL SPAs should use the Authorization Code Grant with PKCE or the Implicit Grant (if PKCE is not feasible) to obtain an access token.
|
||||
|
||||
While APIs are vital for communication between applications and services, they don't directly participate in user authentication. Instead, they often authorize client requests based on access tokens issued by an authorization server. APIs in ZITADEL use grant types like JWT Profile or Basic Authentication to access the authorization server's introspection endpoint for token validation.
|
||||
|
||||
## A real-world scenario
|
||||
|
||||
Suppose there is a news portal web app that allows users to browse through various news articles and personalize their news feed based on their preferences. The back-end API handles fetching and delivering news content from the database.
|
||||
|
||||
**Front-End Login**: A user visits the news portal and opts to log in for a personalized news feed. They are redirected to the Identity Provider’s (IdP) login page, where they authenticate with their credentials. Upon successful authentication, the IdP issues access and ID tokens to the front-end app.
|
||||
|
||||
** Back-End API Communication**: When the user browses through the news feed, the front-end app makes an API request to the back-end, including the access token in the Authorization header. The back-end API, upon receiving the request, uses the IdP’s introspection endpoint to validate the access token. Once validated, it fetches personalized news data based on the user's preferences from the news database.
|
||||
|
||||
While it is true that the back-end API typically needs to authenticate with the IdP, in this specific use case, the back-end API can work with a client credential / JWT since it's not a public client. This means that instead of relying on user-specific authentication, the back-end API can obtain a client credential (such as a client ID and client secret) from the IdP to authenticate itself and validate the access token received from the front-end app. This approach ensures secure communication between the front-end app, the back-end API, and the IdP, while still allowing the back-end API to access user-specific data and provide personalized news feeds.
|
||||
|
||||
## A simplified example with a React frontend and a Python Flask API
|
||||
|
||||
In this example, the application is a web-based quote generator that employs a secure user authentication system via ZITADEL. The functionality of the app is outlined below:
|
||||
|
||||
1. Upon starting, the application provides a login button
|
||||
2. The user is then redirected to ZITADEL's login page to enter their credentials.
|
||||
3. Once the login is successful, the application then greets the user by extracting the user's name, thus providing a personalized experience.
|
||||
4. The application presents an option for the user to generate a quote via a button. Upon pressing this button, the front-end application communicates with the back-end API using the user's access token received from ZITADEL.
|
||||
5. The back-end API introspects the access token for validity using ZITADEL's introspection endpoint. If the token is valid, the API generates a quote and sends it as a response to the front-end application, which is then displayed to the user in their browser.
|
||||
|
||||
## Setting up the applications and ZITADEL
|
||||
|
||||
|
||||
All code and instructions to run the sample application can be found at [https://github.com/zitadel/example-quote-generator-app/](https://github.com/zitadel/example-quote-generator-app/). You can also find the steps for the integration between the front-end, back-end API, and ZITADEL in the README.md.
|
||||
|
||||
You can create the front-end application (User Agent) and the API in the same project or in a different project. In this example, we have created both in one. Configure the applications with appropriate settings (as instructed).
|
||||
|
||||
<img src="/docs/img/guides/solution-scenarios/frontend-calling-backend-API_1.png" alt="User Agent and API applications in a single project"/>
|
||||
|
||||
|
||||
### Front-end login with ZITADEL
|
||||
|
||||
- You must create a User Agent application in your project to add login to your React application using the Authorization Code with PKCE flow. This allows the front-end application to integrate with ZITADEL to enable user authentication and authorization.
|
||||
- In the React front-end application, configure the ZITADEL OIDC client settings, including the client ID, ZITADEL URLs, redirect URIs, and required scopes.
|
||||
- Implement the login flow, authentication callbacks, and token handling logic in the front-end application.
|
||||
- When a user visits the front-end application, they are presented with a login option.
|
||||
- Upon clicking the login button, the frontend initiates the Authorization Code with PKCE authentication flow and redirects the user to the ZITADEL login page. The user enters their credentials and authenticates with ZITADEL. Authorization Code Flow returns an authorization code to the client application, which can then exchange it for an ID token and an access token directly. This provides the benefit of not exposing any tokens to the user agent and possibly other malicious applications with access to the user agent.
|
||||
- You must set up the required scopes and claims to ensure the front-end and back-end can exchange data securely. It’s important to note that when specifying the scope when calling the token API, the scope must contain the project ID of the ZITADEL project in which the API resides (to enable token validation by the back-end API):`scope:'openid profile email urn:zitadel:iam:org:project:id:<API_PROJECT_ID>:aud'`
|
||||
- Also, we want to include user info inside the token to avoid calling the user info endpoint, so go to Token Settings in the front-end app and select User Info inside ID Token.
|
||||
- After a successful authentication, ZITADEL generates an access token and an ID token.
|
||||
- The front-end application receives these tokens and stores them securely (e.g., in browser storage).
|
||||
|
||||
### Token exchange and user information
|
||||
|
||||
- Once the frontend obtains the tokens, it can extract certain information from the ID token itself (e.g., user ID, email, etc.) without making an additional request.
|
||||
- If more user information is required, the frontend can use the access token to call the ZITADEL User Info endpoint. This endpoint provides additional user details, such as name, profile picture, etc.
|
||||
|
||||
### Back-end API communication
|
||||
|
||||
- To communicate with the back-end API, the front-end includes the access token in the Authorization header of API requests.
|
||||
- The back-end API receives the request and needs to validate and authorize the token before processing the request.
|
||||
- The API performs token introspection using ZITADEL's introspection endpoint to validate the access token. This API uses Basic Authentication to invoke the [introspection endpoint](/docs/apis/openidoauth/endpoints#introspection_endpoint), which means it sends its client ID and client secret along with the access token received.
|
||||
- If the token is valid and active, the API proceeds to handle the requested action or fetch data from the underlying data sources.
|
||||
@@ -276,24 +276,10 @@ And with that, configuring ZITADEL for our application is complete. Now we can m
|
||||
|
||||
### 2. Prerequisites
|
||||
|
||||
To follow along with this tutorial, you will need to have both React and Visual Studio Code (VSCode) installed on your machine.
|
||||
|
||||
<b> React </b>
|
||||
To follow along with this tutorial, you will need to have both Node.js and Visual Studio Code (VSCode) installed on your machine.
|
||||
|
||||
To install React, you will need to have Node.js installed on your system. You can download and install Node.js from [here](https://nodejs.org/).
|
||||
|
||||
Once you have Node.js installed, you can use the following command to install React:
|
||||
|
||||
``` npm install -g react ```
|
||||
|
||||
This will install the latest version of React globally on your system. You can then verify the installation by running the following command:
|
||||
|
||||
``` react -v ```
|
||||
|
||||
This should output the version of React that you have installed.
|
||||
|
||||
<b> Visual Studio Code </b>
|
||||
|
||||
To install Visual Studio Code, go to their [website](https://code.visualstudio.com/) and download and install the version for your operating system.
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
title: Cloud Service
|
||||
custom_edit_url: null
|
||||
---
|
||||
## Introduction
|
||||
|
||||
This annex of the [Framework Agreement](terms-of-service) describes the service levels offered by us for our Services.
|
||||
|
||||
@@ -28,4 +27,13 @@ The following regions will be available when using our cloud service. This list
|
||||
- **Switzerland**: Exclusively on Swiss region
|
||||
- **GDPR safe countries**: Exclusively [Adequate Countries](https://ec.europa.eu/info/law/law-topic/data-protection/international-dimension-data-protection/adequacy-decisions_en) as recognized by the European Commission under the GDPR
|
||||
|
||||
Last revised: June 14, 2022
|
||||
## Backup
|
||||
|
||||
Our backup strategy executes daily full backups and differential backups on much higher frequency.
|
||||
In a disaster recovery scenario, our goal is to guarantee a recovery point objective (RPO) of 1h, and a higher but similar recovery time objective (RTO).
|
||||
Under normal operations, RPO and RTO goals are below 1 minute.
|
||||
|
||||
If you you have different requirements we provide you with a flexible approach to backup, restore, and transfer data (f.e. to a self-hosted setup) through our APIs.
|
||||
Please consult the [migration guides](../guides/migrate/introduction.md) for more information.
|
||||
|
||||
Last revised: June 21, 2023
|
||||
@@ -167,6 +167,27 @@ module.exports = {
|
||||
"guides/integrate/pat",
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "category",
|
||||
label: "Build your own Login-UI",
|
||||
link: {
|
||||
type: "generated-index",
|
||||
title: "Build your own Login-UI",
|
||||
slug: "/guides/integrate/login-ui",
|
||||
description:
|
||||
"In the following guides you will learn how to create your own login ui with our APIs. The different scenarios like username/password, external identity provider, etc will be shown.",
|
||||
|
||||
},
|
||||
collapsed: true,
|
||||
items: [
|
||||
"guides/integrate/login-ui/username-password",
|
||||
"guides/integrate/login-ui/external-login",
|
||||
"guides/integrate/login-ui/select-account",
|
||||
"guides/integrate/login-ui/password-reset",
|
||||
"guides/integrate/login-ui/logout",
|
||||
"guides/integrate/login-ui/oidc-standard"
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "category",
|
||||
label: "Configure identity providers",
|
||||
@@ -273,6 +294,7 @@ module.exports = {
|
||||
"guides/solution-scenarios/saas",
|
||||
"guides/solution-scenarios/domain-discovery",
|
||||
"guides/solution-scenarios/configurations",
|
||||
"guides/solution-scenarios/frontend-calling-backend-API",
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
BIN
docs/static/img/guides/login-ui/external-login-flow.png
vendored
Normal file
BIN
docs/static/img/guides/login-ui/external-login-flow.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 280 KiB |
BIN
docs/static/img/guides/login-ui/oidc-flow.png
vendored
Normal file
BIN
docs/static/img/guides/login-ui/oidc-flow.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 254 KiB |
BIN
docs/static/img/guides/login-ui/password-reset-flow.png
vendored
Normal file
BIN
docs/static/img/guides/login-ui/password-reset-flow.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 219 KiB |
BIN
docs/static/img/guides/login-ui/username-password-flow.png
vendored
Normal file
BIN
docs/static/img/guides/login-ui/username-password-flow.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 270 KiB |
BIN
docs/static/img/guides/solution-scenarios/frontend-calling-backend-API_1.png
vendored
Normal file
BIN
docs/static/img/guides/solution-scenarios/frontend-calling-backend-API_1.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 559 KiB |
Reference in New Issue
Block a user