Skip to main content

Login Users into your Application


This guide will show you how to use ZITADEL to login users into your application (authentication). It will guide you step-by-step through the basics and point out on how to customize process.

OIDC / OAuth Flow#

OAuth and therefore OIDC know three different application types:

  • Web (Server-side web applications such as java, .net, ...)
  • Native (native, mobile or desktop applications)
  • User Agent (single page applications / SPA, generally JavaScript executed in the browser)

Depending on the app type you're trying to register, there are small differences. But regardless of the app type we recommend using Proof Key for Code Exchange (PKCE).

Please read the following guide about the different-client-profiles and why to use PKCE.

Code Flow#

For a basic understanding of OAuth and its flows, we'll briefly describe the most important flow: Authorization Code.

The following diagram demonstrates a basic authorization_code flow:

Authorization Code Flow

  1. When an unauthenticated user visits your application,
  2. you will create an authorization request to the authorization endpoint.
  3. The Authorization Server (ZITADEL) will send an HTTP 302 to the user's browser, which will redirect him to the login UI.
  4. The user will have to authenticate using the demanded auth mechanics.
  5. Your application will be called on the registered callback path (redirect_uri) and be provided an authorization_code.
  6. This authorization_code must then be sent together with you applications authentication (client_id + client_secret) to the token_endpoint
  7. In exchange the Authorization Server (ZITADEL) will return an access_token and if requested a refresh_token and in the case of OIDC an id_token as well
  8. The access_token can then be used to call a Resource Server (API). The token will be sent as Authorization Header.

This flow is the same when using PKCE or JWT with Private Key for authentication.

Create Application#

To create an application, open your project in Console and start by clicking on the "New" button in the Application section.

Application type#

This will start a wizard asking you for an application name and a type.

Auth Request#

To initialize the user authentication, you will have to create an authorization request using HTTP GET in the user agent (browser) on /authorize with at least the following parameters:

  • client_id: this tells the authorization server which application it is, copy from Console
  • redirect_uri: where the authorization code is sent to after the user authentication, must be one of the registered in the previous step
  • response_type: if you want to have a code (authorization code flow) or directly a token (implicit flow), so when ever possible use code
  • scope: what scope you want to grant to the access_token / id_token, minimum is openid, if you're unsure what you need you might start with openid profile email

We recommend always using two additional parameters state and nonce. The former enables you to transfer a state through the authentication process. The latter is used to bind the client session with the id_token and to mitigate replay attacks.

Depending on your authentication method you might need to provide additional parameters:

Additional parameters and customization#

There are additional parameters and values you can provide to satisfy your use case and to customize the user's authentication flow. Please check the authorization_endpoint reference in the OAuth / OIDC documentation.


Regardless of a successful or error response from the authorization_endpoint, the authorization server will call your callback endpoint you provided by the redirect_uri.


If the redirect_uri is not provided, was not registered or anything other prevents the auth server form returning the response to the client, the error will be display directly to the user on the auth server.

Upon successful authentication you'll be given a code and if provided the unmodified state parameter. You will need this code in the token request.

If a parameter was missing, malformed or any other error occurred, your answer will contain an error stating the error type, possibly an error_description providing some information about the error and its reason and the state parameter. Check the error response section in the authorization_endpoint reference.

Token request#

Next you will have to exchange the given code for the tokens. For this HTTP POST request (form-urlencoded) you will need to provide the following:

  • code: the code that was issued from the authorization request
  • grant_type: must be authorization_code
  • redirect_uri: callback uri where the code was sent to. Must match exactly the redirect_uri of the authorization request

Depending on your authentication method you'll need additional headers and parameters:

Send your client_id and the previously generated string as code_verifier for us to recompute the code_challenge of the authorization request:

curl --request POST \--url \--header 'Content-Type: application/x-www-form-urlencoded' \--data grant_type=authorization_code \--data code=${code} \--data redirect_uri=${redirect_uri} \--data client_id=${client_id} \--data code_verifier=${code_verifier}