mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-18 05:52:51 +00:00
# Which Problems Are Solved Several links in the docs point at repository paths that no longer exist, so they 404 on GitHub: - The `load-test` directory was renamed to `benchmark`. The benchmarks page still links to `load-test`, `load-test/Makefile` and `load-test/README.md` (5 occurrences). - `apps/docs/content/index.mdx` links to `CONTRIBUTING.mdx`, but the file is `CONTRIBUTING.md`. - The login-app guide links to `apps/login/src/middleware.ts`, which was renamed to `apps/login/src/proxy.ts` in the Next.js 16 upgrade (#11629). # How the Problems Are Solved - Point the benchmarks page at `benchmark/`, `benchmark/Makefile` and `benchmark/README.md`. The `#test` anchor still resolves — `benchmark/README.md` has a `### Test` heading. - Fix the `CONTRIBUTING.md` extension. - Point the middleware example at `apps/login/src/proxy.ts`. Verified by extracting every `github.com/zitadel/zitadel/{blob,tree}/main/...` link from `apps/docs/content` and resolving each one against the working tree — all 14 distinct paths now exist. # Additional Changes - Prose in the benchmarks page that names the directory ("the load-test Makefile", "the load-test readme") now says "benchmark". Generic uses of "load-test"/"load-testing" as an activity are left as they are. # Additional Context - The versioned docs under `apps/docs/content/v4.13`–`v4.16` contain the same stale links, but those directories are generated at build time from release tags by `apps/docs/scripts/fetch-remote-content.mjs` and are gitignored, so they cannot be fixed from `main`. The published pages for those versions will keep the old links. - `apps/docs/scripts/check-links.ts` skips anything starting with `http`, which is why these went unnoticed. Teaching it to resolve `github.com/zitadel/zitadel/blob/main/<path>` links against the working tree would catch this class of breakage in CI — not done here to keep the PR focused. Co-authored-by: Claude Opus 5 <[email protected]>
152 lines
8.1 KiB
Plaintext
152 lines
8.1 KiB
Plaintext
---
|
|
title: Login App
|
|
description: "Building a custom login application with ZITADEL: an overview of the OIDC and Session API integration."
|
|
sidebar_label: Login App
|
|
---
|
|
|
|
To replace the old embedded Login built with Golang and to showcase the use of our session and OIDC APIs, we've created the new [Login app](https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md#contribute-to-login).
|
|
|
|
## Used Apps And Packages
|
|
|
|
- **Login app**: The Login app used by ZITADEL Cloud, powered by Next.js
|
|
- `@zitadel/proto`: Typescript implementation of Protocol Buffers, suitable for web browsers and Node.js.
|
|
- `@zitadel/client`: Core components for establishing a client connection
|
|
|
|
## Login App
|
|
|
|
The new implementation of the Login app is based on Next.js and implements the [OIDC standard](./oidc-standard) by proxying requests to the ZITADEL backend and using the session API.
|
|
The UI uses the branding and behaves based on the policies and settings of your instance or organization.
|
|
It is also allows users to authenticate directly (without an OIDC context) and self service their account.
|
|
Its set of features will increase with time and its progress will be tracked [here](./login-app#implemented-features).
|
|
|
|
### Architectural Overview
|
|
|
|
The new Login app consists of a confidential (backend) part and a browser (client side) part.
|
|
In addition to that, the OIDC specification builds upon a proxy which is set up in the Next.js middleware. It rewrites requests of the paths `/.well-known/:path*`, `/oauth/:path*`, `/oidc/:path*` to ZITADEL.
|
|
|
|
The backend side of the application is authorized using a service account's personal access token.
|
|
This token is used to fetch policies and settings from your instances or organization which define how users are authenticated and how the Login app is displayed.
|
|
|
|
The frontend side of the application communicates to the backend side by using a cookie which is set by the server.
|
|
The cookie consists of an id and a token and is bound to a session which is updated continuously.
|
|
|
|
The following illustration shows the architecture of the Login app and a potential authentication code flow starting from an application which implements the OIDC specification respectively.
|
|
|
|

|
|
|
|
_Note that the illustration is just a representation of the architecture and may not specify actual endpoints._
|
|
|
|
The flow starts by the `/authorize` endpoint which is intercepted by the Login app and forwarded to ZITADEL.
|
|
ZITADEL interprets the request and specifically redirects back to the Login app.
|
|
It does so by redirecting to `/login`.
|
|
The Login app is then able to load an [AuthRequest](/reference/api/oidc/zitadel.oidc.v2.OIDCService.GetAuthRequest).
|
|
|
|
The Auth Request defines how users proceed to authenticate. If no special prompts or scopes are set, the Login app brings up the `/loginname` page.
|
|
The /loginname page allows to enter loginname or email of a user which is then used to search for a user.
|
|
If the user is found, a session is created and set as cookie, then the user is redirected to the available authentication method page.
|
|
While the users continues and provides more information, the cookie is hydrated with this information until a final state is reached.
|
|
|
|
The communication from the browser to the server is done by [NextJS Server Actions](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations).
|
|
The OIDC Auth request is always passed in the url to have a context to the ongoing authentication flow.
|
|
|
|
If enough user information is retrieved and the user is authenticated according to the policies, the flow is finalized by [requesting a the callback url](/reference/api/oidc/zitadel.oidc.v2.OIDCService.CreateCallback) for the auth request and the user is redirected back to the application.
|
|
The application can then request a token calling the /token endpoint of the Login app which is proxied to the ZITADEL API.
|
|
|
|
### Implemented features
|
|
|
|
#### OIDC Standard
|
|
|
|
- [x] Authorization Code Flow with PKCE
|
|
- [x] AuthRequest `hintUserId`
|
|
- [x] AuthRequest `loginHint`
|
|
- [x] AuthRequest `prompt`
|
|
- [x] Login
|
|
- [x] Select Account
|
|
- [x] Create
|
|
- [x] None
|
|
- [ ] Consent
|
|
- Scopes
|
|
- [x] `openid email profile address`
|
|
- [x] `offline access`
|
|
- [x] `urn:zitadel:iam:org:idp:id:{idp_id}`
|
|
- [x] `urn:zitadel:iam:org:project:id:zitadel:aud`
|
|
- [x] `urn:zitadel:iam:org:id:{orgid}`
|
|
- [x] `urn:zitadel:iam:org:domain:primary:{domain}`
|
|
- [ ] AuthRequest UI locales
|
|
- Multifactor
|
|
- [x] Passkeys
|
|
- [x] TOTP
|
|
- [x] OTP via email
|
|
- [x] OTP via SMS
|
|
- Passwordless
|
|
- [x] Passkeys
|
|
- Security Prompts
|
|
- [x] Setup Passkey as Passwordless method
|
|
- [x] Setup TOTP as Multifactor
|
|
- [ ] Password Change
|
|
- Login
|
|
- [x] Email Password
|
|
- [x] Passkey
|
|
- [x] IDPs
|
|
- [x] Google
|
|
- [x] GitHub
|
|
- [x] GitLab
|
|
- [x] Azure
|
|
- [ ] Apple
|
|
- Register
|
|
- [x] Email Password
|
|
- [x] Passkey
|
|
|
|
#### Self service
|
|
|
|
The self service part of the application allows to load the Login app without an OIDC flow.
|
|
Authenticated users are directly able to self service their account.
|
|
|
|
- [ ] Change user information
|
|
- [ ] Password Change
|
|
- [x] Setup Passkey
|
|
- [x] Setup Multifactor
|
|
- [x] Passkeys
|
|
- [x] TOTP
|
|
- [x] OTP via email
|
|
- [x] OTP via SMS
|
|
- [x] Setup Multifactor Passkey (U2F)
|
|
- [x] Validate Account (email verification)
|
|
|
|
### Setup
|
|
|
|
In order to run the new Login app, make sure to follow the instructions in the [contribution guide](https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md#contribute-to-login).
|
|
|
|
#### How to setup domains for OIDC
|
|
|
|
When setting up the new Login app for OIDC, the domain must be registered on your instance and use https.
|
|
To register your login domain on your instance, [add](/apis/resources/admin/admin-service-add-instance-trusted-domain) your domain on your instances Trusted Domains.
|
|
|
|
#### OIDC Proxy
|
|
|
|
When setting up the new Login app for OIDC, ensure it meets the following requirements:
|
|
|
|
- The OIDC Proxy is deployed and running on HTTPS
|
|
- The OIDC Proxy sets `x-zitadel-public-host` which is the host, your Login app is deployed to `ex. login.example.com`.
|
|
- The OIDC Proxy sets `x-zitadel-instance-host` which is the host of your instance `ex. test-hdujwl.zitadel.cloud`.
|
|
|
|
You can review an example implementation of a middleware [here](https://github.com/zitadel/zitadel/blob/main/apps/login/src/proxy.ts).
|
|
|
|
#### Deploy to Vercel
|
|
|
|
<a href="https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fzitadel%2Fzitadel&env=ZITADEL_API_URL,ZITADEL_SERVICE_USER_ID,ZITADEL_SERVICE_USER_TOKEN&root-directory=apps/login&envDescription=Setup%20a%20service%20account%20with%20IAM_LOGIN_CLIENT%20membership%20on%20your%20instance%20and%20provide%20its%20id%20and%20personal%20access%20token.&project-name=zitadel-login&repository-name=zitadel-login" target="_blank" rel="noopener noreferrer" style={{cursor: "pointer", display: "inline-block", padding: "2px"}}>
|
|
<img src="https://vercel.com/button" alt="Deploy with Vercel" style={{pointerEvents: "none", display: "block"}}/>
|
|
</a>
|
|
|
|
To deploy your own version on Vercel, navigate to your instance and create a service account.
|
|
Create a personal access token (PAT) for the user and copy and set it as `ZITADEL_SERVICE_USER_TOKEN`, then navigate to Default settings and make sure it gets `IAM_LOGIN_CLIENT` permissions.
|
|
Finally set your instance url as `ZITADEL_API_URL`. Make sure to set it without trailing slash.
|
|
Also ensure your login domain is registered on your instance by adding it as a [Trusted Domain](/apis/resources/admin/admin-service-add-instance-trusted-domain).
|
|
|
|
If you want to enforce users to have their email verified, you can set the optional `EMAIL_VERIFICATION` variable to `true` in your environment and your users will be enforced to verify their email address before they can log in.
|
|
|
|
By default, verification codes are not automatically submitted on page load. This protects against enterprise email link scanners that pre-fetch URLs and could inadvertently consume one-time codes before users click them.
|
|
If you want to enable automatic code submission (e.g. for a smoother UX when link scanners are not a concern), set `NEXT_PUBLIC_AUTO_SUBMIT_CODE` to `true`.
|
|
|
|

|