docs: update angular quickstart (#3025)

* docs: make angular quickstart user friendlier

* docs: improve angular quickstart

 Closes: #3042
This commit is contained in:
Elio Bischof 2022-01-20 10:13:34 +01:00 committed by GitHub
parent 24aef8d16e
commit c3d4db10ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,56 +2,56 @@
title: Angular
---
This Integration guide shows you the recommended way to integrate **ZITADEL** into your Angular Application.
It demonstrates how to add a user login to your application and fetch some data from the user info endpoint.
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.
At the end of the guide you should have an application able to login a user and read the user 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 [Template](https://github.com/caos/zitadel-examples/tree/main/angular) in Github. Note that our **ZITADEL Console** is also written in Angular and can therefore be used as a reference.
> This documentation refers to our [example](https://github.com/caos/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 do 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.
Select Web Application and continue.
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.
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.
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.
![Create app in console](/img/angular/app-create-light.png)
### Redirect URLs
### Redirect URIs
A redirect URL is a URL in your application where ZITADEL redirects the user after they have authenticated. Set your url to the domain the web app will be deployed to or use `localhost:4200` for development as Angular will be running on port 4200.
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 [sample](https://github.com/caos/zitadel-examples/tree/main/angular) project you downloaded from our templates, you should set the Allowed Callback URL to <http://localhost:4200/auth/callback>. You will also have to set dev mode to `true` as this will enable unsecure http for the moment.
> If you are following along with the [example](https://github.com/caos/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 redirectURI 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
After successful app creation a popup will appear showing you your clientID.
Copy your client ID as it will be needed in the next step.
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.
## Angular Setup
### Install Angular dependencies
Now that you have your web application configured on the ZITADEL side, you can go ahead and integrate your Angular client.
You need to install an oauth / oidc client to connect with ZITADEL. Run the following command:
### Install Angular Dependencies
You need to install an OAuth / OIDC client to connect with ZITADEL. Run the following command:
```bash
npm install angular-oauth2-oidc
```
This library helps integrating ZITADEL Authentication in your Angular Application.
### Create and Configure Auth Module
### Create and configure Auth Module
Add the Auth module to your Angular imports in AppModule and setup the AuthConfig in a constant above.
Add _OAuthModule_ to your Angular imports in _AppModule_ and provide the _AuthConfig_ in the providers' section. Also, ensure you import the _HTTPClientModule_.
```ts
...
import { AuthConfig, OAuthModule } from 'angular-oauth2-oidc';
import { HttpClientModule } from '@angular/common/http';
const authConfig: AuthConfig = {
scope: 'openid profile email',
@ -65,31 +65,39 @@ const authConfig: AuthConfig = {
};
@NgModule({
declarations: [
AppComponent,
SignedoutComponent,
],
...
imports: [
OAuthModule..forRoot(),
OAuthModule.forRoot(),
HttpClientModule,
...
providers: [
{
provide: AuthConfig,
useValue: authConfig
}
...
```
Set **openid**, **profile** and **email** as scope, **code** as responseType, and oidc to **true**.
Then create a 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.
You can use Angulars schematics to do so:
You can use Angulars schematics to do so:
```bash
ng g component services/authentication
ng g service services/authentication
```
This will create an AuthenticationService automatically for you.
Copy the following code to your service. This code provides a function `authenticate()` which redirects the user to ZITADEL. After the user has logged in it will be redirected back to your redirectURI set in Auth Module and Console. Make sure both correspond, otherwise ZITADEL will throw 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
import { Injectable } from '@angular/core';
import { AuthConfig, OAuthService } from 'angular-oauth2-oidc';
import { BehaviorSubject, from, Observable } from 'rxjs';
import { StatehandlerService } from './statehandler.service';
@Injectable({
providedIn: 'root'
})
export class AuthenticationService {
private _authenticated: boolean = false;
private readonly _authenticationChanged: BehaviorSubject<
@ -141,8 +149,8 @@ export class AuthenticationService {
}
```
Our template includes a statehandler service to redirect the user back to the route where he initially came from. It saves the route information to a unique id so that the user can be redirected back after a successful authentication.
If you don't need such a behaviour you can escape the following lines from the `authenticate()` method above.
Our example includes a _StatehandlerService_ to redirect the user back to the route where he initially came from.
If you don't need such behavior, you can omit the following line from the `authenticate()` method above.
```ts
...
@ -150,7 +158,7 @@ const newState = setState ? await this.statehandler.createState().toPromise() :
...
```
If you decide to use it provide the service in the `app.module` and make sure it gets initialized first using angulars `APP_INITIALIZER`.
If you decide to use the _StatehandlerService_, provide it in the `app.module`. Make sure it gets initialized first using Angulars `APP_INITIALIZER`. You find the service implementation in the [example](https://github.com/caos/zitadel-examples/tree/main/angular).
```ts
@ -180,24 +188,23 @@ providers: [
...
```
### Add Login in your application
### Add Login to Your Application
To login a user, a component or a guard is needed.
To log a user in, you need a component or a guard.
- A component provides a button prompting the user to start the login flow.
`authenticate()` redirects your user to ZITADEL.ch for authentication. Upon successfull Authentication, ZITADEL will redirect the user back to your previously defined Redirect URL.
- A component could provide a button, starting the login flow on click.
- A guard can be setup to check if the user has a valid **Access Token** to proceed. This will check if the user has a stored **accesstoken** in storage or otherwise prompt the user to login.
- A guard that starts a login flow once a user without a stored valid access token tries to access a protected route.
The use of this components totally depends on your application. In most cases you need both.
Using these components heavily depends on your application. In most cases, you need both.
To create a component use:
Generate a component like this:
```bash
ng g component components/login
```
and then inject the authService to call `authenticate()`.
Inject the _AuthenticationService_ and call `authenticate()` on some click event.
Same for the guard:
@ -205,21 +212,24 @@ Same for the guard:
ng g guard guards/auth
```
This code shows the AuthGuard used in our Console.
This code shows the _AuthGuard_ used in ZITADEL Console.
```ts
import { AuthService } from 'src/app/services/auth.service';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthenticationService } from '../services/authentication.service';
@Injectable({
providedIn: 'root',
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private auth: AuthService) { }
public canActivate(
_: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
): Observable<boolean> | Promise<boolean> | boolean {
constructor(private auth: AuthenticationService) { }
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
if (!this.auth.authenticated) {
return this.auth.authenticate();
}
@ -228,7 +238,7 @@ export class AuthGuard implements CanActivate {
}
```
it can easily be added to your RouterModule.
Add the guard to your _RouterModule_ similar to this:
```ts
...
@ -241,25 +251,26 @@ const routes: Routes = [
...
```
> Note: To complete the code flow, `authenticate()` needs to be called twice. You may have to add a guard to your callback url to make sure it will complete the flow.
> Note: Make sure you redirect the user from your callback URL to a guarded page, so `authenticate()` is called again and the access token is stored.
```ts
...
{
path: 'auth/callback',
canActivate: [AuthGuard],
redirectTo: 'user',
},
....
```
### Add Logout in your application
### Add Logout to Your Application
The authService and Library also provides a useful function for logging out your users. Just call `auth.signout()` to log out your user. Note that you can also configure your Logout Redirect URL 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
import { AuthService } from 'src/app/services/auth.service.ts';
import { AuthenticationService } from 'src/app/services/authentication.service';
export class SomeComponentWithLogout {
constructor(private authService: AuthService){}
constructor(private authService: AuthenticationService){}
public signout(): Promise<void> {
return this.authService.signout();
@ -269,11 +280,11 @@ export class SomeComponentWithLogout {
### Show User Information
To fetch user data, ZITADELS user info endpoint has to be called. This data contains sensitive information and artifacts related to your users identity and the scopes you defined in your Auth Config.
Our AuthService already includes a function called getOIDCUser(). You can call it whereever you need this information.
To fetch user data, ZITADEL's user info endpoint has to be called. This data contains sensitive information and artifacts related to the current user's identity and the scopes you defined in your _AuthConfig_.
Our _AuthenticationService_ already includes a method called _getOIDCUser()_. You can call it wherever you need this information.
```ts
import { AuthenticationService } from 'src/app/services/auth.service.ts';
import { AuthenticationService } from 'src/app/services/authentication.service';
public user$: Observable<any>;
@ -282,7 +293,7 @@ constructor(private auth: AuthenticationService) {
}
```
and in your html
And in your HTML file:
```html
<div *ngIf="user$ | async as user">
@ -292,14 +303,14 @@ and in your html
## Completion
You have successfully integrated ZITADEL in your Angular Application!
You have successfully integrated your Angular application with ZITADEL!
If you get stuck consider checking out our [template](https://github.com/caos/zitadel-examples/tree/main/angular) application which includes all the mentioned functionality of this quickstart. You can simply start by cloning the repo and replacing the AuthConfig in the app.module with your own configuration. If your run into issues don't hesitate to contact us or raise an issue on [Github](https://github.com/caos/zitadel).
If you get stuck, consider checking out our [example](https://github.com/caos/zitadel-examples/tree/main/angular) application. It includes all the mentioned functionality of this quickstart. You can simply start by cloning the repository and replacing the _AuthConfig_ in the _AppModule_ by your own configuration. If you run into issues, contact us or raise an issue on [GitHub](https://github.com/caos/zitadel).
![App in console](/img/angular/app-screen.png)
### Whats next?
### What's next?
Now you can proceed implementing our APIs to include Authorization. Refer to our [Docs](../../apis/introduction) or checkout our Console Code on [Github](https://github.com/caos/zitadel) which is using GRPC to access data.
Now that you have enabled authentication, it's time to add authorization to your application using ZITADEL APIs. Refer to the [docs](../../apis/introduction) or check out our ZITADEL Console code on [GitHub](https://github.com/caos/zitadel) which is using gRPC to access data.
For more information about creating an angular application we refer to [Angular](https://angular.io/start) and for more information about the used oauth/oidc library consider reading their docs at [angular-oauth2-oidc](https://github.com/manfredsteyer/angular-oauth2-oidc).
For more information about creating an Angular application, refer to [Angular](https://angular.io/start) and for more information about the OAuth/OIDC library used above, consider reading their docs at [angular-oauth2-oidc](https://github.com/manfredsteyer/angular-oauth2-oidc).