mirror of
https://github.com/zitadel/zitadel.git
synced 2025-04-01 15:42:17 +00:00
docs: quickstart changes for v2 (#3906)
* docs: v2 quickstarts * flutter div * html * html * common https:/[your-domain]-[random-string].zitadel.cloud
This commit is contained in:
parent
252d0fa8b5
commit
91771bc49b
@ -3,32 +3,32 @@ title: Angular
|
|||||||
---
|
---
|
||||||
|
|
||||||
This integration guide shows you the recommended way to integrate ZITADEL into your Angular application.
|
This integration guide shows you the recommended way to integrate ZITADEL into your Angular application.
|
||||||
It shows how to add user login to your application and fetch some data from the user info endpoint.
|
It shows how to add user login to your application and fetch some data from the user info endpoint.
|
||||||
|
|
||||||
At the end of the guide, your application has login functionality and has access to the current user's profile.
|
At the end of the guide, your application has login functionality and has access to the current user's profile.
|
||||||
|
|
||||||
> This documentation refers to our [example](https://github.com/zitadel/zitadel-examples/tree/main/angular) in GitHub. Note that we've written ZITADEL Console in Angular, so you can also use that as a reference.
|
> This documentation refers to our [example](https://github.com/zitadel/zitadel-examples/tree/main/angular) in GitHub. Note that we've written ZITADEL Console in Angular, so you can also use that as a reference.
|
||||||
|
|
||||||
## Setup Application and Get Keys
|
## Setup Application and Get Keys
|
||||||
|
|
||||||
Before we can start building our application, we have to do a few configuration steps in ZITADEL Console.
|
Before we can start building our application, we have to do a few configuration steps in ZITADEL Console.
|
||||||
You will need to provide some information about your app. We recommend creating a new app to start from scratch. Navigate to your [Project](https://console.zitadel.ch/projects), then add a new application at the top of the page.
|
You will need to provide some information about your app. We recommend creating a new app to start from scratch. Navigate to your Project, then add a new application at the top of the page.
|
||||||
Select Web application type and continue.
|
Select Web application type and continue.
|
||||||
We recommend you use [Authorization Code](../../apis/openidoauth/grant-types#authorization-code) in combination with [Proof Key for Code Exchange (PKCE)](../../apis/openidoauth/grant-types#proof-key-for-code-exchange) for all web applications.
|
We recommend you use [Authorization Code](../../apis/openidoauth/grant-types#authorization-code) in combination with [Proof Key for Code Exchange (PKCE)](../../apis/openidoauth/grant-types#proof-key-for-code-exchange) for all web applications.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Redirect URIs
|
### Redirect URIs
|
||||||
|
|
||||||
With the Redirect URIs field, you tell ZITADEL where it is allowed to redirect users to after authentication. For development, you can set dev mode to `true` to enable insecure HTTP and redirect to a `localhost` URI.
|
With the Redirect URIs field, you tell ZITADEL where it is allowed to redirect users to after authentication. For development, you can set dev mode to `true` to enable insecure HTTP and redirect to a `localhost` URI.
|
||||||
|
|
||||||
> If you are following along with the [example](https://github.com/zitadel/zitadel-examples/tree/main/angular), set dev mode to `true` and the Redirect URIs to <http://localhost:4200/auth/callback>.
|
> If you are following along with the [example](https://github.com/zitadel/zitadel-examples/tree/main/angular), set dev mode to `true` and the Redirect URIs to <http://localhost:4200/auth/callback>.
|
||||||
|
|
||||||
If you want to redirect the users back to a route on your application after they have logged out, add an optional redirect in the Post Logout URIs field.
|
If you want to redirect the users back to a route on your application after they have logged out, add an optional redirect in the Post Logout URIs field.
|
||||||
|
|
||||||
Continue and create the application.
|
Continue and create the application.
|
||||||
|
|
||||||
### Client ID and Secret
|
### Client ID
|
||||||
|
|
||||||
After successful app creation, a pop-up will appear, showing the app's client ID. Copy the client ID, as you will need it to configure your Angular client.
|
After successful app creation, a pop-up will appear, showing the app's client ID. Copy the client ID, as you will need it to configure your Angular client.
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ const authConfig: AuthConfig = {
|
|||||||
responseType: 'code',
|
responseType: 'code',
|
||||||
oidc: true,
|
oidc: true,
|
||||||
clientId: 'YOUR-CLIENT-ID', // replace with your appid
|
clientId: 'YOUR-CLIENT-ID', // replace with your appid
|
||||||
issuer: '<YOUR-DOMAIN>', // eg. https://acme-jdo9fs.zitadel.cloud
|
issuer: 'https:/[your-domain]-[random-string].zitadel.cloud', // replace with your instance
|
||||||
redirectUri: 'http://localhost:4200/auth/callback',
|
redirectUri: 'http://localhost:4200/auth/callback',
|
||||||
postLogoutRedirectUri: 'http://localhost:4200/signedout', // optional
|
postLogoutRedirectUri: 'http://localhost:4200/signedout', // optional
|
||||||
requireHttps: false // required for running locally
|
requireHttps: false // required for running locally
|
||||||
@ -68,14 +68,14 @@ const authConfig: AuthConfig = {
|
|||||||
...
|
...
|
||||||
imports: [
|
imports: [
|
||||||
OAuthModule.forRoot(),
|
OAuthModule.forRoot(),
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
...
|
...
|
||||||
providers: [
|
providers: [
|
||||||
{
|
{
|
||||||
provide: AuthConfig,
|
provide: AuthConfig,
|
||||||
useValue: authConfig
|
useValue: authConfig
|
||||||
}
|
}
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
Set _openid_, _profile_ and _email_ as scope, _code_ as responseType, and oidc to _true_. Then create an authentication service to provide the functions to authenticate your user.
|
Set _openid_, _profile_ and _email_ as scope, _code_ as responseType, and oidc to _true_. Then create an authentication service to provide the functions to authenticate your user.
|
||||||
@ -89,63 +89,62 @@ ng g service services/authentication
|
|||||||
Copy the following code to your service. This code provides a function `authenticate()` which redirects the user to ZITADEL. After successful login, ZITADEL redirects the user back to the redirect URI configured in _AuthModule_ and ZITADEL Console. Make sure both correspond, otherwise ZITADEL throws an error.
|
Copy the following code to your service. This code provides a function `authenticate()` which redirects the user to ZITADEL. After successful login, ZITADEL redirects the user back to the redirect URI configured in _AuthModule_ and ZITADEL Console. Make sure both correspond, otherwise ZITADEL throws an error.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from "@angular/core";
|
||||||
import { AuthConfig, OAuthService } from 'angular-oauth2-oidc';
|
import { AuthConfig, OAuthService } from "angular-oauth2-oidc";
|
||||||
import { BehaviorSubject, from, Observable } from 'rxjs';
|
import { BehaviorSubject, from, Observable } from "rxjs";
|
||||||
|
|
||||||
import { StatehandlerService } from './statehandler.service';
|
import { StatehandlerService } from "./statehandler.service";
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: "root",
|
||||||
})
|
})
|
||||||
export class AuthenticationService {
|
export class AuthenticationService {
|
||||||
private _authenticated: boolean = false;
|
private _authenticated: boolean = false;
|
||||||
private readonly _authenticationChanged: BehaviorSubject<
|
private readonly _authenticationChanged: BehaviorSubject<boolean> =
|
||||||
boolean
|
new BehaviorSubject(this.authenticated);
|
||||||
> = new BehaviorSubject(this.authenticated);
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private oauthService: OAuthService,
|
private oauthService: OAuthService,
|
||||||
private authConfig: AuthConfig,
|
private authConfig: AuthConfig,
|
||||||
private statehandler: StatehandlerService,
|
private statehandler: StatehandlerService
|
||||||
) { }
|
) {}
|
||||||
|
|
||||||
public get authenticated(): boolean {
|
public get authenticated(): boolean {
|
||||||
return this._authenticated;
|
return this._authenticated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get authenticationChanged(): Observable<boolean> {
|
||||||
|
return this._authenticationChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getOIDCUser(): Observable<any> {
|
||||||
|
return from(this.oauthService.loadUserProfile());
|
||||||
|
}
|
||||||
|
|
||||||
|
public async authenticate(setState: boolean = true): Promise<boolean> {
|
||||||
|
this.oauthService.configure(this.authConfig);
|
||||||
|
|
||||||
|
this.oauthService.strictDiscoveryDocumentValidation = false;
|
||||||
|
await this.oauthService.loadDiscoveryDocumentAndTryLogin();
|
||||||
|
|
||||||
|
this._authenticated = this.oauthService.hasValidAccessToken();
|
||||||
|
|
||||||
|
if (!this.oauthService.hasValidIdToken() || !this.authenticated) {
|
||||||
|
const newState = setState
|
||||||
|
? await this.statehandler.createState().toPromise()
|
||||||
|
: undefined;
|
||||||
|
this.oauthService.initCodeFlow(newState);
|
||||||
}
|
}
|
||||||
|
this._authenticationChanged.next(this.authenticated);
|
||||||
|
|
||||||
public get authenticationChanged(): Observable<boolean> {
|
return this.authenticated;
|
||||||
return this._authenticationChanged;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public getOIDCUser(): Observable<any> {
|
public signout(): void {
|
||||||
return from(this.oauthService.loadUserProfile());
|
this.oauthService.logOut();
|
||||||
}
|
this._authenticated = false;
|
||||||
|
this._authenticationChanged.next(false);
|
||||||
public async authenticate(
|
}
|
||||||
setState: boolean = true,
|
|
||||||
): Promise<boolean> {
|
|
||||||
this.oauthService.configure(this.authConfig);
|
|
||||||
|
|
||||||
this.oauthService.strictDiscoveryDocumentValidation = false;
|
|
||||||
await this.oauthService.loadDiscoveryDocumentAndTryLogin();
|
|
||||||
|
|
||||||
this._authenticated = this.oauthService.hasValidAccessToken();
|
|
||||||
|
|
||||||
if (!this.oauthService.hasValidIdToken() || !this.authenticated) {
|
|
||||||
const newState = setState ? await this.statehandler.createState().toPromise() : undefined;
|
|
||||||
this.oauthService.initCodeFlow(newState);
|
|
||||||
}
|
|
||||||
this._authenticationChanged.next(this.authenticated);
|
|
||||||
|
|
||||||
return this.authenticated;
|
|
||||||
}
|
|
||||||
|
|
||||||
public signout(): void {
|
|
||||||
this.oauthService.logOut();
|
|
||||||
this._authenticated = false;
|
|
||||||
this._authenticationChanged.next(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -215,26 +214,35 @@ ng g guard guards/auth
|
|||||||
This code shows the _AuthGuard_ used in ZITADEL Console.
|
This code shows the _AuthGuard_ used in ZITADEL Console.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from "@angular/core";
|
||||||
import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, UrlTree } from '@angular/router';
|
import {
|
||||||
import { Observable } from 'rxjs';
|
ActivatedRouteSnapshot,
|
||||||
import { AuthenticationService } from '../services/authentication.service';
|
CanActivate,
|
||||||
|
RouterStateSnapshot,
|
||||||
|
UrlTree,
|
||||||
|
} from "@angular/router";
|
||||||
|
import { Observable } from "rxjs";
|
||||||
|
import { AuthenticationService } from "../services/authentication.service";
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: "root",
|
||||||
})
|
})
|
||||||
export class AuthGuard implements CanActivate {
|
export class AuthGuard implements CanActivate {
|
||||||
|
constructor(private auth: AuthenticationService) {}
|
||||||
|
|
||||||
constructor(private auth: AuthenticationService) { }
|
|
||||||
|
|
||||||
canActivate(
|
canActivate(
|
||||||
route: ActivatedRouteSnapshot,
|
route: ActivatedRouteSnapshot,
|
||||||
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
|
state: RouterStateSnapshot
|
||||||
if (!this.auth.authenticated) {
|
):
|
||||||
return this.auth.authenticate();
|
| Observable<boolean | UrlTree>
|
||||||
}
|
| Promise<boolean | UrlTree>
|
||||||
return this.auth.authenticated;
|
| boolean
|
||||||
}
|
| UrlTree {
|
||||||
|
if (!this.auth.authenticated) {
|
||||||
|
return this.auth.authenticate();
|
||||||
|
}
|
||||||
|
return this.auth.authenticated;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -267,14 +275,14 @@ const routes: Routes = [
|
|||||||
Call `auth.signout()` for logging the current user out. Note that you can also configure a logout redirect URI if you want your users to be redirected after logout.
|
Call `auth.signout()` for logging the current user out. Note that you can also configure a logout redirect URI if you want your users to be redirected after logout.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import { AuthenticationService } from 'src/app/services/authentication.service';
|
import { AuthenticationService } from "src/app/services/authentication.service";
|
||||||
|
|
||||||
export class SomeComponentWithLogout {
|
export class SomeComponentWithLogout {
|
||||||
constructor(private authService: AuthenticationService){}
|
constructor(private authService: AuthenticationService) {}
|
||||||
|
|
||||||
public signout(): Promise<void> {
|
public signout(): Promise<void> {
|
||||||
return this.authService.signout();
|
return this.authService.signout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -297,7 +305,7 @@ And in your HTML file:
|
|||||||
|
|
||||||
```html
|
```html
|
||||||
<div *ngIf="user$ | async as user">
|
<div *ngIf="user$ | async as user">
|
||||||
<p>{{user | json}}</p>
|
<p>{{user | json}}</p>
|
||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -45,14 +45,14 @@ You may want to change the Flutter SDK version in `pubspec.yaml` from
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.7.0 <3.0.0'
|
sdk: ">=2.7.0 <3.0.0"
|
||||||
```
|
```
|
||||||
|
|
||||||
to
|
to
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.12.0 <3.0.0'
|
sdk: ">=2.12.0 <3.0.0"
|
||||||
```
|
```
|
||||||
|
|
||||||
With this, you'll enable "nullable by default" mode in Flutter, as well as new language features.
|
With this, you'll enable "nullable by default" mode in Flutter, as well as new language features.
|
||||||
@ -257,7 +257,7 @@ Future<void> _authenticate() async {
|
|||||||
AuthorizationTokenRequest(
|
AuthorizationTokenRequest(
|
||||||
'<<CLIENT_ID>>', // Client ID of the native application
|
'<<CLIENT_ID>>', // Client ID of the native application
|
||||||
'<<CALLBACK_URL>>', // The registered url from zitadel (e.g. ch.myexample.app://signin)
|
'<<CALLBACK_URL>>', // The registered url from zitadel (e.g. ch.myexample.app://signin)
|
||||||
issuer: '<<ISSUER>>', // most of the cases: https://issuer.zitadel.ch
|
issuer: '<<ISSUER>>', // most of the cases: https:/[your-domain]-[random-string].zitadel.cloud
|
||||||
scopes: [
|
scopes: [
|
||||||
'openid',
|
'openid',
|
||||||
'profile',
|
'profile',
|
||||||
@ -268,7 +268,7 @@ Future<void> _authenticate() async {
|
|||||||
);
|
);
|
||||||
|
|
||||||
final userInfoResponse = await get(
|
final userInfoResponse = await get(
|
||||||
Uri.parse('https://api.zitadel.ch/oauth/v2/userinfo'),
|
Uri.parse('https://[your-instance].zitadel.cloud/oauth/v2/userinfo'),
|
||||||
headers: {
|
headers: {
|
||||||
HttpHeaders.authorizationHeader: 'Bearer ${result.accessToken}',
|
HttpHeaders.authorizationHeader: 'Bearer ${result.accessToken}',
|
||||||
HttpHeaders.acceptHeader: 'application/json; charset=UTF-8'
|
HttpHeaders.acceptHeader: 'application/json; charset=UTF-8'
|
||||||
@ -333,7 +333,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
final userInfoResponse = await get(
|
final userInfoResponse = await get(
|
||||||
Uri.parse('https://api.zitadel.ch/oauth/v2/userinfo'),
|
Uri.parse('https:/[your-domain]-[random-string].zitadel.cloud/oauth/v2/userinfo'), // replace with your instance
|
||||||
headers: {
|
headers: {
|
||||||
HttpHeaders.authorizationHeader: 'Bearer ${result.accessToken}',
|
HttpHeaders.authorizationHeader: 'Bearer ${result.accessToken}',
|
||||||
HttpHeaders.acceptHeader: 'application/json; charset=UTF-8'
|
HttpHeaders.acceptHeader: 'application/json; charset=UTF-8'
|
||||||
@ -407,10 +407,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
|
|
||||||
If you run this application, you can authenticate with a valid ZITADEL user.
|
If you run this application, you can authenticate with a valid ZITADEL user.
|
||||||
|
|
||||||
<div style={{display:'flex', 'justify-content': 'center'}}>
|
<div style={{display: 'grid', 'grid-column-gap': '1rem', 'grid-template-columns': '1fr 1fr'}}>
|
||||||
<div style={{display:'flex', 'align-items': 'center'}}>
|
|
||||||
<img src="/img/flutter/not-authed.png" alt="Unauthenticated" height="500px" />
|
<img src="/img/flutter/not-authed.png" alt="Unauthenticated" height="500px" />
|
||||||
<span style={{padding:'1rem'}}>becomes</span>
|
|
||||||
<img src="/img/flutter/authed.png" alt="Flutter Authenticated" height="500px" />
|
<img src="/img/flutter/authed.png" alt="Flutter Authenticated" height="500px" />
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -40,47 +40,47 @@ NextAuth.js exposes a REST API which is used by your client.
|
|||||||
To setup your configuration, create a file called [...nextauth].tsx in `pages/api/auth`.
|
To setup your configuration, create a file called [...nextauth].tsx in `pages/api/auth`.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import NextAuth from 'next-auth';
|
import NextAuth from "next-auth";
|
||||||
|
|
||||||
export const ZITADEL = {
|
export const ZITADEL = {
|
||||||
id: "zitadel",
|
id: "zitadel",
|
||||||
name: "zitadel",
|
name: "zitadel",
|
||||||
type: "oauth",
|
type: "oauth",
|
||||||
version: "2.0",
|
version: "2",
|
||||||
scope: "openid profile email",
|
wellKnown: process.env.ZITADEL_ISSUER,
|
||||||
params: { response_type: "code", grant_type: "authorization_code" },
|
authorization: {
|
||||||
authorizationParams: { grant_type: "authorization_code", response_type: "code" },
|
params: {
|
||||||
accessTokenUrl: "https://api.zitadel.dev/oauth/v2/token",
|
scope: "openid email profile",
|
||||||
requestTokenUrl: "https://api.zitadel.dev/oauth/v2/token",
|
|
||||||
authorizationUrl: "https://accounts.zitadel.dev/oauth/v2/authorize",
|
|
||||||
profileUrl: "https://api.zitadel.dev/oauth/v2/userinfo",
|
|
||||||
protection: "pkce",
|
|
||||||
async profile(profile, tokens) {
|
|
||||||
console.log(profile, tokens);
|
|
||||||
return {
|
|
||||||
id: profile.sub,
|
|
||||||
name: profile.name,
|
|
||||||
email: profile.email,
|
|
||||||
image: profile.picture
|
|
||||||
};
|
|
||||||
},
|
|
||||||
clientId: process.env.ZITADEL_CLIENT_ID,
|
|
||||||
session: {
|
|
||||||
jwt: true,
|
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
idToken: true,
|
||||||
|
checks: ["pkce", "state"],
|
||||||
|
client: {
|
||||||
|
token_endpoint_auth_method: "none",
|
||||||
|
},
|
||||||
|
async profile(profile) {
|
||||||
|
return {
|
||||||
|
id: profile.sub,
|
||||||
|
name: profile.name,
|
||||||
|
firstName: profile.given_name,
|
||||||
|
lastName: profile.family_name,
|
||||||
|
email: profile.email,
|
||||||
|
loginName: profile.preferred_username,
|
||||||
|
image: profile.picture,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
clientId: process.env.ZITADEL_CLIENT_ID,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default NextAuth({
|
export default NextAuth({
|
||||||
providers: [
|
providers: [ZITADEL],
|
||||||
ZITADEL
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
Replace the endpoints `https://api.zitadel.dev/` with `https://api.zitadel.ch/` if your using a ZITADEL CLOUD tier or your own endpoint if your using a self hosted ENTERPRISE tier respectively.
|
Replace the endpoints `https:/[your-domain]-[random-string].zitadel.cloud` with your instance or if your using a ZITADEL CLOUD tier or your own endpoint if your using a self hosted ENTERPRISE tier respectively.
|
||||||
|
|
||||||
We recommend using the Authentication Code flow secured by PKCE for the Authentication flow.
|
We recommend using the Authentication Code flow secured by PKCE for the Authentication flow.
|
||||||
To be able to connect to ZITADEL, navigate to your [Console Projects](https://console.zitadel.ch/projects) create or select an existing project and add your app selecting WEB, then PKCE, and then add `http://localhost:3000/api/auth/callback/zitadel` as redirect url to your app.
|
To be able to connect to ZITADEL, navigate to your Console Projects, create or select an existing project and add your app selecting WEB, then PKCE, and then add `http://localhost:3000/api/auth/callback/zitadel` as redirect url to your app.
|
||||||
|
|
||||||
For simplicity reasons we set the default to the one that next-auth provides us. You'll be able to change the redirect later if you want to.
|
For simplicity reasons we set the default to the one that next-auth provides us. You'll be able to change the redirect later if you want to.
|
||||||
|
|
||||||
@ -95,6 +95,7 @@ Create a file `.env` in the root of the project and add the following keys to it
|
|||||||
```
|
```
|
||||||
NEXTAUTH_URL=http://localhost:3000
|
NEXTAUTH_URL=http://localhost:3000
|
||||||
ZITADEL_CLIENT_ID=[yourClientId]
|
ZITADEL_CLIENT_ID=[yourClientId]
|
||||||
|
ZITADEL_ISSUER=https:/[your-domain]-[random-string].zitadel.cloud
|
||||||
```
|
```
|
||||||
|
|
||||||
# User interface
|
# User interface
|
||||||
@ -107,7 +108,7 @@ Note that signIn method requires the id of the provider we provided earlier, and
|
|||||||
import { signIn, signOut, useSession } from 'next-auth/client';
|
import { signIn, signOut, useSession } from 'next-auth/client';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
const [session, loading] = useSession();
|
const { data: session } = useSession();
|
||||||
...
|
...
|
||||||
{!session && <>
|
{!session && <>
|
||||||
Not signed in <br />
|
Not signed in <br />
|
||||||
@ -129,13 +130,14 @@ To allow session state to be shared between pages - which improves performance,
|
|||||||
Take a loot at the template `_app.tsx`.
|
Take a loot at the template `_app.tsx`.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import { Provider } from 'next-auth/client';
|
import { SessionProvider } from "next-auth/react";
|
||||||
|
|
||||||
function MyApp({ Component, pageProps }) {
|
function MyApp({ Component, pageProps }) {
|
||||||
return <Provider
|
return (
|
||||||
session={pageProps.session} >
|
<SessionProvider session={pageProps.session}>
|
||||||
<Component {...pageProps} />
|
<Component {...pageProps} />
|
||||||
</Provider>;
|
</SessionProvider>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MyApp;
|
export default MyApp;
|
||||||
@ -143,17 +145,19 @@ export default MyApp;
|
|||||||
|
|
||||||
Last thing: create a `profile.tsx` in /pages which renders the callback page.
|
Last thing: create a `profile.tsx` in /pages which renders the callback page.
|
||||||
|
|
||||||
## Learn More
|
```ts
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
To learn more about Next.js, take a look at the following resources:
|
import styles from "../styles/Home.module.css";
|
||||||
|
|
||||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
export default function Profile() {
|
||||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
return (
|
||||||
|
<div className={styles.container}>
|
||||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
|
<h1>Login successful</h1>
|
||||||
|
<Link href="/">
|
||||||
## Deploy on Vercel
|
<button>Back to Home</button>
|
||||||
|
</Link>
|
||||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
</div>
|
||||||
|
);
|
||||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
}
|
||||||
|
```
|
||||||
|
@ -10,7 +10,7 @@ At the end of the guide you should have an application able to login a user and
|
|||||||
## Setup Application and get Keys
|
## Setup Application and get Keys
|
||||||
|
|
||||||
Before we can start building our application we have to do a few configuration steps in ZITADEL Console.
|
Before we can start building our application we have to do a few configuration steps in ZITADEL Console.
|
||||||
You will need to provide some information about your app. We recommend creating a new app to start from scratch. Navigate to your [Project](https://console.zitadel.ch/projects) and add a new application at the top of the page.
|
You will need to provide some information about your app. We recommend creating a new app to start from scratch. Navigate to your Project and add a new application at the top of the page.
|
||||||
Select User Agent and continue. More about the different app types can you find [here](https://docs.zitadel.com/docs/guides/authorization/oauth-recommended-flows#different-client-profiles).
|
Select User Agent and continue. More about the different app types can you find [here](https://docs.zitadel.com/docs/guides/authorization/oauth-recommended-flows#different-client-profiles).
|
||||||
We recommend that you use [Authorization Code](../../apis/openidoauth/grant-types#authorization-code) in combination with [Proof Key for Code Exchange](../../apis/openidoauth/grant-types#proof-key-for-code-exchange) for all web applications.
|
We recommend that you use [Authorization Code](../../apis/openidoauth/grant-types#authorization-code) in combination with [Proof Key for Code Exchange](../../apis/openidoauth/grant-types#proof-key-for-code-exchange) for all web applications.
|
||||||
|
|
||||||
@ -54,38 +54,40 @@ This library helps integrating ZITADEL Authentication in your React Application.
|
|||||||
With the installed oidc pakage you will need an AuthProvider which should contain the OIDC configuration.
|
With the installed oidc pakage you will need an AuthProvider which should contain the OIDC configuration.
|
||||||
|
|
||||||
The oidc configuration should contain **openid**, **profile** and **email** as scope and **code** as responseType.
|
The oidc configuration should contain **openid**, **profile** and **email** as scope and **code** as responseType.
|
||||||
In the code below the authority is already set to the issuer of zitadel.ch you can find this in the ZITADEL Console on you application.
|
In the code below make sure to change the issuer to your instance url. You can find this in the ZITADEL Console on you application.
|
||||||
Replace the clientId value 'YOUR-CLIENT-ID' with the generated client id of you application in ZITADEL Console.
|
Replace the clientId value 'YOUR-CLIENT-ID' with the generated client id of you application in ZITADEL Console.
|
||||||
|
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
import React from "react";
|
||||||
import React from 'react';
|
import { AuthProvider } from "oidc-react";
|
||||||
import { AuthProvider } from 'oidc-react';
|
import "./App.css";
|
||||||
import './App.css';
|
|
||||||
const oidcConfig = {
|
const oidcConfig = {
|
||||||
onSignIn: async (response: any) => {
|
onSignIn: async (response: any) => {
|
||||||
alert('You logged in :' + response.profile.given_name + ' ' + response.profile.family_name);
|
alert(
|
||||||
window.location.hash = '';
|
"You logged in :" +
|
||||||
},
|
response.profile.given_name +
|
||||||
authority: 'https://issuer.zitadel.ch',
|
" " +
|
||||||
clientId:
|
response.profile.family_name
|
||||||
'YOUR-CLIENT-ID',
|
);
|
||||||
responseType: 'code',
|
window.location.hash = "";
|
||||||
redirectUri: 'http://localhost:3000/',
|
},
|
||||||
scope: 'openid profile email'
|
authority: "https:/[your-domain]-[random-string].zitadel.cloud", // replace with your instance
|
||||||
|
clientId: "YOUR-CLIENT-ID",
|
||||||
|
responseType: "code",
|
||||||
|
redirectUri: "http://localhost:3000/",
|
||||||
|
scope: "openid profile email",
|
||||||
};
|
};
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<AuthProvider {...oidcConfig}>
|
<AuthProvider {...oidcConfig}>
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<header className="App-header">
|
<header className="App-header">
|
||||||
<p>Hello World</p>
|
<p>Hello World</p>
|
||||||
</header>
|
</header>
|
||||||
</div>
|
</div>
|
||||||
</AuthProvider>
|
</AuthProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
@ -100,7 +102,7 @@ npm start
|
|||||||
```
|
```
|
||||||
|
|
||||||
Your browser should automatically open the app site or just go to `http://localhost:3000/`.
|
Your browser should automatically open the app site or just go to `http://localhost:3000/`.
|
||||||
On opening the app in the browser you will be redirected to the login of zitadel.ch
|
On opening the app in the browser you will be redirected to the login of your instance.
|
||||||
After successfully authenticating your user, you will get back to you application.
|
After successfully authenticating your user, you will get back to you application.
|
||||||
It should show a popup which says: **You logged in {FirstName} {LastName}**
|
It should show a popup which says: **You logged in {FirstName} {LastName}**
|
||||||
|
|
||||||
|
BIN
docs/static/img/angular/app-create-light.png
vendored
BIN
docs/static/img/angular/app-create-light.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 175 KiB |
BIN
docs/static/img/angular/app-create.png
vendored
Normal file
BIN
docs/static/img/angular/app-create.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 259 KiB |
Loading…
x
Reference in New Issue
Block a user