docs: improve documentation for v2 release (#4046)

* WIP: docs(proxy): describe proxy settings

* fix nginx

* refactor (docs): deploy and operate sections

* chore: ignore package-lock since we use yarn

* chore: update to rc1

* chore: broken links

* chore: update yarn

* docs: move disclaimer to bottom

* chore: fix broken links

* Update docs/docs/guides/operate/tls_modes.mdx

Co-authored-by: Fabi <[email protected]>

* test caddy files

* syntax highlight

* traefik example

* refactor: docs

* refactor

* working state

* got a working state

* remove bar

* mark rate limits for update

* remove zitadel.ch

* fix cases

* docs: zitadel quickstart

* docs: zitadel quickstart

* docs: create app and project

* docs: move customer portal docs to guides manage cloud

* docs: move customer portal docs to guides manage cloud

* docs: move customer portal docs to guides manage cloud

* docs: add help me choose in the quickstart

* docs: broken links

* fix broken links

* Update knative guide

* styling

* docs: support customer portal

* update to main instead v2-alpha

* use version 2 tag

* docs: images

* docs: move authentication and authorization guides to integrate

* docs: quickstart use examples

* docs: lb example

* fix broken link

* docs: update userinfo endpoints

* docs: update userinfo endpoints

* fix oidc endpoint

* docs: remove unused endpoints in app.module

Co-authored-by: Fabi <[email protected]>
Co-authored-by: Fabienne <[email protected]>
Co-authored-by: Livio Amstutz <[email protected]>
This commit is contained in:
Florian Forster
2022-07-29 10:13:45 +02:00
committed by GitHub
co-authored by Fabi Fabienne Livio Amstutz
parent fb52575f79
commit 3c3bce1a6b
123 changed files with 3212 additions and 25673 deletions
@@ -0,0 +1,118 @@
---
title: .NET
---
This integration guide shows you how to integrate **ZITADEL** into your .NET application.
It demonstrates how to fetch some data from the ZITADEL management API.
At the end of the guide you should have an application able to read the details of your organization.
If you need any other information about the .NET SDK go to the [documentation](https://caos.github.io/zitadel-net/) of the SDK itself.
## Prerequisites
The client [SDK](https://github.com/zitadel/zitadel-net) will handle all necessary OAuth 2.0 requests and send the required headers to the ZITADEL API.
All that is required, is a service account with an Org Owner (or another role, depending on the needed api requests) role assigned and its key JSON.
However, we recommend you read the guide on [how to access ZITADEL API](../../guides/integrate/access-zitadel-apis) and the associated guides for a basic knowledge of :
- [Recommended Authorization Flows](../../guides/integrate/oauth-recommended-flows.md)
- [Service Users](../../guides/integrate/serviceusers.md)
> Be sure to have a valid key JSON and that its service account is either ORG_OWNER or at least ORG_OWNER_VIEWER before you continue with this guide.
## .NET Setup
### Create a .NET application
Use the IDE of your choice or the command line to create a new application.
```bash
dotnet new web
```
### Install the package
Install the package via nuget
```bash
dotnet add package Zitadel.Api
```
### Create example client
Change the program.cs file to the content below. This will create a client for the management api and call its `GetMyUsers` function.
The SDK will make sure you will have access to the API by retrieving a Bearer Token using JWT Profile with the provided scopes (`openid` and `urn:zitadel:iam:org:project:id:{projectID}:aud`).
Make sure to fill the const `apiUrl`, `apiProject` and `personalAccessToken` with your own instance data. The used vars below are from a test instance, to show you how it should look.
The apiURL is the domain of your instance you can find it on the instance detail in the Customer Portal or in the Console
The apiProject you will find in the ZITADEL project in the first organization of your instance.
```csharp
// This file contains two examples:
// 1. An example with a service account "personal access token" to access the ZITADEL API.
// 2. An example with a service account "jwt profile key" to access the ZITADEL API.
using Zitadel.Api;
using Zitadel.Credentials;
const string apiUrl = "https://zitadel-libraries-l8boqa.zitadel.cloud";
const string personalAccessToken = "ge85fvmgTX4XAhjpF0XGpelB2vn9LZanJaqmUQDuf7iTpKVowb44LFl-86pqY2mfJCEoIOk";
// or create the token provider directly:
// new StaticTokenProvider(token)
var client = Clients.AuthService(new(apiUrl, ITokenProvider.Static(personalAccessToken)));
var result = await client.GetMyUserAsync(new());
Console.WriteLine($"User: {result.User}");
const string apiProject = "170078979166961921";
var serviceAccount = ServiceAccount.LoadFromJsonString(
@"
{
""type"": ""serviceaccount"",
""keyId"": ""170084658355110145"",
""key"": ""-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAnQisbU4FuLmjLR9I2Q01Rm9Mx6WySat2mbxgmOzu04oXuESI\nyS+RkiimdN0khjqouBftYqtVes7yngMLq3E8hMCwv/kLE+YeXphZXnn8tps8M2gV\n7S//uCp9LooK9qeh0lSkOqIsh0atj/l7NAHFxnhuNhfmn8XIYJNLVNSj5yzTri5E\nSn92SAsUQLSONgr7IEmIjcuPtYeU0iLvVno52ljZHnPX2WJ0HEZv44nZpkR4qBfv\n3hJzNx7sd4TdPGHHugJD8jdG/X4bAxwL5XGHZu18cUVM5RerSMpFQHSuIGgpKmK4\nWlM1AJGeut6EX/SrCxUDvhyOnXAgqhunTUmi6QIDAQABAoIBAHn7y92Y1y743X3m\nqHMbJIBTYyRPXaCGljm0MKF6o8clpWlZq5wE3KLZ+vwa8Q1oMbnXtGqKR3t/mM4P\n9Ze2/djtyh9GOUm632qCFCIkxp+fFPOl7ipyt8V7FAT77KpP6490eqKlacunppmJ\nph/vJJAY6xwQEvGX9SC4KrN5/txLKXbVtR3V2RXy9sxbbL4cpnklmRBMeXQkpwEM\nTKELUr5Rmhg9KvS3yALgVv0dIRtOA8Z995R234hXfY0St48YEvZtsxeme47u2CVl\nHJcVH4aa9Sw6XlgAEQBxqbQHpcLvUIu3XempO7VfGklWE6OlGuEcnUWpJCD8jMZW\nPYtt9LUCgYEAwi8josS3Iyto+DMJjJKCw175N2cmFMxBGu9Rw4aHjTiN57z7AUkn\nbmT44WnSmc1bCLC+nMB34vhiEyBKXYrH7zgbeMO8QDG3aO6gXdod/IdsieZR8E3b\ngUA1wtZYyRbc7eo8U4Nqkv1NXVRuDJkz/Mfoy+m1BVKcW7YeZaaZN9MCgYEAzwYB\n/LAiJoyx5UPwuieizlT7kHI7uvZRo4oLx+cZipNCJ0NGKgX4l1NIYLaNDbCoT9N0\nylico+kn+nihzDmD6SjY2hHGSIHk7AnJOcW+Bk5TfsYb8clxfgX40udLMIS0F13R\nrJt0gD9x0O3AZv4MV9cSI0/Md0tbWePgrLI44NMCgYEAojj7TlmEnY8AbIlGqvci\n4tCO5qf3elyA712LMwtKZsIeWsDX+OUCWglkmfvsAq06JfJx60YnYagbVtsdBTSR\nftmiqarrs71U+gaQVpeHgZYpKLMPNO/2Nu5Le2/SUHwXKXML3sDk4dNXNGb6YPAE\nLGNdqiyeG8o98agdkNIzIh0CgYEAlTGhMPfGRL3UXoNN8vopjEUWXozUmvJ090S/\nJLtZXtKtNBp5cEOJWZT9biVhFeKgCZc8ba7ahA29b/aLs+AnPlrfnJh+qzZhQfHz\ngJ0PSwAbkBs5fFBOaCHppiRlvXuFRemo95m4pcwTPBx7Mj4Xqx4lxij2E2rNVMSy\n4AI4l10CgYBwefqXt8B+D+0EvmhyHk19Tk8/fPelclJUv/IVI59c0F9UMAA2rD1U\nNW6k9251OGU7mQkztluNvl13qtAW/DveOjkFeDJIMzhFjravpLQXhUK4ETnM44YL\nFbClVGJaHYSHgOkNpcN5lYVLoyEvzv9rEPwBqpZRVnwWj6L+/I2L5Q==\n-----END RSA PRIVATE KEY-----\n"",
""userId"": ""170079991923474689""
}");
client = Clients.AuthService(
new(
apiUrl,
ITokenProvider.ServiceAccount(
serviceAccount,
apiUrl,
apiProject)));
result = await client.GetMyUserAsync(new());
Console.WriteLine($"User: {result.User}");
```
### Test client
After you have configured everything correctly, you can simply start the example by:
```bash
dotnet run
```
This will output something similar to:
```
User: {"FirstName": "MyName", "LastName": "MyLastName" ... }
```
## Completion
You have successfully used the ZITADEL .NET SDK to call the auth API!
To use the auth API you will not need a specific role, because only an authenticated user is needed.
For accessing the admin or management API the user will need some specific roles.
If you encountered an error (e.g. `code = PermissionDenied desc = No matching permissions found`),
ensure your service user has the required permissions by assigning the `ORG_OWNER` or `ORG_OWNER_VIEWER` role
and check the mentioned [guides](#prerequisites) at the beginning.
If you've run into any other problem, don't hesitate to contact us or raise an issue on [ZITADEL](https://github.com/zitadel/zitadel/issues) or in the [SDK](https://github.com/zitadel/zitadel-go/issues).
### Whats next?
Now you can proceed implementing our APIs by adding more calls.
Checkout more [examples from the SDK](https://github.com/zitadel/zitadel-go/blob/main/example) or refer to our [API Docs](../../apis/introduction).
> This guide will be updated soon to show you how to use the SDK for your own API as well.
+153
View File
@@ -0,0 +1,153 @@
---
title: Go
---
This integration guide shows you how to integrate **ZITADEL** into your Go application.
It demonstrates how to fetch some data from the ZITADEL management API.
At the end of the guide you should have an application able to read the details of your organization.
## Prerequisites
The client [SDK](https://github.com/zitadel/zitadel-go) will handle all necessary OAuth 2.0 requests and send the required headers to the ZITADEL API using our [OIDC client library](https://github.com/zitadel/oidc).
All that is required, is a service account with an Org Owner (or another role, depending on the needed api requests) role assigned and its key JSON.
However, we recommend you read the guide on [how to access ZITADEL API](../../guides/integrate/access-zitadel-apis) and the associated guides for a basic knowledge of :
- [Recommended Authorization Flows](../../guides/integrate/oauth-recommended-flows.md)
- [Service Users](../../guides/integrate/serviceusers.md)
> Be sure to have a valid key JSON and that its service account is either ORG_OWNER or at least ORG_OWNER_VIEWER before you continue with this guide.
## Go Setup
### Add Go SDK to your project
You need to add the SDK into Go Modules by:
```bash
go get github.com/zitadel/zitadel-go/v2
```
### Create example client
Create a new go file with the content below. This will create a client for the management api and call its `GetMyOrg` function.
The SDK will make sure you will have access to the API by retrieving a Bearer Token using JWT Profile with the provided scopes (`openid` and `urn:zitadel:iam:org:project:id:{projectID}:aud`).
Make sure to fill the vars `issuer`, `api`, `projectID `and `orgID`
The issuer and api is the domain of your instance you can find it on the instance detail in the ZITADEL Cloud Customer Portal or in the ZITADEL Console.
The projectID you will find in the ZITADEL project in the first organization of your instance and the orgID on the first organization.
```go
package main
import (
"context"
"flag"
"log"
"github.com/zitadel/oidc/pkg/oidc"
"github.com/zitadel/zitadel-go/v2/pkg/client/management"
"github.com/zitadel/zitadel-go/v2/pkg/client/middleware"
"github.com/zitadel/zitadel-go/v2/pkg/client/zitadel"
pb "github.com/zitadel/zitadel-go/v2/pkg/client/zitadel/management"
)
var (
issuer = flag.String("issuer", "", "issuer of your ZITADEL instance (in the form: https://<instance>.zitadel.cloud or https://<yourdomain>)")
api = flag.String("api", "", "gRPC endpoint of your ZITADEL instance (in the form: <instance>.zitadel.cloud:443 or <yourdomain>:443)")
projectID = flag.String("projectID", "", "ZITADEL projectID in your instance")
orgID = flag.String("orgID", "", "orgID to set for overwrite example")
)
func main() {
flag.Parse()
client, err := management.NewClient(
*issuer,
*api,
[]string{oidc.ScopeOpenID, zitadel.ScopeProjectID(*projectID)},
)
if err != nil {
log.Fatalln("could not create client", err)
}
defer func() {
err := client.Connection.Close()
if err != nil {
log.Println("could not close grpc connection", err)
}
}()
ctx := context.Background()
resp, err := client.GetMyOrg(ctx, &pb.GetMyOrgRequest{})
if err != nil {
log.Fatalln("call failed: ", err)
}
log.Printf("%s was created on: %s", resp.Org.Name, resp.Org.Details.CreationDate.AsTime())
respOverwrite, err := client.GetMyOrg(middleware.SetOrgID(ctx, *orgID), &pb.GetMyOrgRequest{})
if err != nil {
log.Fatalln("call failed: ", err)
}
log.Printf("%s was created on: %s", respOverwrite.Org.Name, respOverwrite.Org.Details.CreationDate.AsTime())
```
#### Key JSON
To provide the key JSON to the SDK, simply set an environment variable `ZITADEL_KEY_PATH` with the path to the JSON as value.
```bash
export ZITADEL_KEY_PATH=/Users/test/servicekey.json
```
For development purposes you should be able to set this in your IDE.
If you're not able to set it via environment variable, you can also pass it with an additional option:
```go
client, err := management.NewClient(
[]string{oidc.ScopeOpenID, zitadel.ScopeZitadelAPI()},
zitadel.WithKeyPath("/Users/test/servicekey.json"),
)
```
### Test client
After you have configured everything correctly, you can simply start the example by:
```bash
go run main.go
```
This will output something similar to:
```
2021/04/21 11:27:36 DemoOrg was created on: 2021-04-08 13:36:05.578194 +0000 UTC
```
## Completion
You have successfully used the ZITADEL Go SDK to call the management API!
If you encountered an error (e.g. `code = PermissionDenied desc = No matching permissions found`),
ensure your service user has the required permissions by assigning the `ORG_OWNER` or `ORG_OWNER_VIEWER` role
and check the mentioned [guides](#prerequisites) at the beginning.
If you've run into any other problem, don't hesitate to contact us or raise an issue on [ZITADEL](https://github.com/zitadel/zitadel/issues) or in the [SDK](https://github.com/zitadel/zitadel-go/issues).
### Whats next?
Now you can proceed implementing our APIs by adding more calls or trying to overwrite the organization context:
```go
respOverwrite, err := client.GetMyOrg(middleware.SetOrgID(ctx, "74161146763996133"), &pb.GetMyOrgRequest{})
if err != nil {
log.Fatalln("call failed: ", err)
}
log.Printf("%s was created on: %s", respOverwrite.Org.Name, respOverwrite.Org.Details.CreationDate.AsTime())
}
```
Checkout more [examples from the SDK](https://github.com/zitadel/zitadel-go/blob/main/example) or refer to our [API Docs](../../apis/introduction).
> This guide will be updated soon to show you how to use the SDK for your own API as well.
@@ -0,0 +1,68 @@
---
title: OAuth 2.0 Proxy
---
<!-- //TODO Florian update this to zitadel.cloud-->
[OAuth2-proxy](https://github.com/oauth2-proxy/oauth2-proxy) is a project which allows services to delegate the authentication flow to a IDP, for example **ZITADEL**
## Configure ZITADEL
### 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 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) for the OAuth 2.0 Proxy.
> Make sure Authentication Method is set to `BASIC` and the Application Type is set to `Web`.
### Redirect URLs
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 proxy will be deployed to or use the default one `http://127.0.0.1:4180/oauth2/callback`.
> If you are following along with the sample 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 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.
Continue and Create the application.
### Client ID and Secret
After successful app creation a popup will appear showing you your clientID as well as a secret.
Copy your client ID and Secrets as it will be needed in the next step.
> Note: You will be able to regenerate the secret at a later time if you loose it.
## OAuth 2.0 Proxy Setup
### Authentication Example
```toml
provider = "oidc"
user_id_claim = "sub" #uses the subject as ID instead of the email
provider_display_name = "ZITADEL"
redirect_url = "http://127.0.0.1:4180/oauth2/callback"
oidc_issuer_url = "https://{your_domain}.zitadel.cloud"
upstreams = [
"https://example.corp.com"
]
email_domains = [
"*"
]
client_id = "{ZITADEL_GENERATED_CLIENT_ID}"
client_secret = "{ZITADEL_GENERATED_CLIENT_SECRET}"
pass_access_token = true
cookie_secret = "{SUPPLY_SOME_SECRET_HERE}"
skip_provider_button = true
cookie_secure = false #localdev only false
http_address = "127.0.0.1:4180" #localdev only
```
> This was tested with version `oauth2-proxy v6.1.1 (built with go1.14.2)`
## Completion
You have successfully integrated ZITADEL in your proxy!
### What next?
+50
View File
@@ -0,0 +1,50 @@
---
title: Overview
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import {Card, CardWrapper} from '../../src/components/card';
Get started with ZITADEL quickly by reading a quickstart or by cloning an example from our [ZITADEL examples](https://github.com/zitadel/zitadel-examples) repo.
<Tabs>
<TabItem value="app" label="Web · Native applications" default>
<CardWrapper>
<Card link="/docs/examples/login/angular" imageSource="/img/tech/angular.svg" title="Angular" description="Add the user login to your application and query some data from the userinfo endpoint" />
<Card link="/docs/examples/login/react" imageSource="/img/tech/react.png" title="React" description="Logs into your application and queries some data from the userinfo endpoint" />
<Card link="/docs/examples/login/flutter" imageSource="/img/tech/flutter.svg" title="Flutter" description="Mobile Application working for iOS and Android that authenticates your user." />
<Card link="/docs/examples/login/nextjs" imageSource="/img/tech/nextjs.svg" title="NextJS" description="A simple application to log into your user account and query some data from User endpoint." />
</CardWrapper>
</TabItem>
<TabItem value="backend" label="Backend · API">
<CardWrapper>
<Card link="/docs/quickstarts/call-zitadel-api/go" imageSource="/img/tech/golang.svg" title="GO" description="Demonstrates how to fetch some data from the ZITADEL management API." />
<Card link="/docs/quickstarts/call-zitadel-api/dot-net" imageSource="/img/tech/dotnet.svg" title=".NET" description="This integration guide shows you how to integrate ZITADEL into your .NET application. It demonstrates how to fetch some data from the ZITADEL management API." />
</CardWrapper>
</TabItem>
<TabItem value="proxy" label="Proxy">
<CardWrapper>
<Card link="/docs/quickstarts/identity-proxy/oauth2-proxy" imageSource="/img/tech/oauth2-proxy.svg" title="OAuth 2.0 Proxy" description="Allows services to delegate the authentication flow to a IDP, for example ZITADEL" />
</CardWrapper>
</TabItem>
</Tabs>
## Clone a sample project
<CardWrapper>
<Card githubLink="https://github.com/zitadel/zitadel-examples/tree/main/java/spring-boot" title="Java" label="Java" />
<Card githubLink="https://github.com/zitadel/zitadel-examples/tree/main/python3" title="Python" label="Python" />
<Card githubLink="https://github.com/zitadel/zitadel-examples/tree/main/angular" title="Angular" label="Web · Mobile Web" />
<Card githubLink="https://github.com/zitadel/zitadel-examples/tree/main/nextjs" title="NextJS" label="Web · Mobile Web" />
</CardWrapper>
## Libraries
| Language | Description | Link |
| ------------ | ---------------------|-------------|
| Go | Go client library for ZITADEL. | [https://github.com/zitadel/zitadel-go](https://github.com/zitadel/zitadel-go)
| .Net | Authentication / Authorization library written in dotnet for the asp.net web application package. | [https://github.com/zitadel/zitadel-net](https://github.com/zitadel/zitadel-net)
| Dart | Dart library for ZITADEL, contains gRPC and API access elements. | [https://github.com/zitadel/zitadel-dart](https://github.com/zitadel/zitadel-dart) |
| Elixir | API Client for the ZITADEL API. | [https://github.com/jshmrtn/zitadel_api](https://github.com/jshmrtn/zitadel_api) |
+12
View File
@@ -0,0 +1,12 @@
---
title: Libraries
---
| Language | Description | Link |
| ------------ | ---------------------|-------------|
| Go | Go client library for ZITADEL. | [https://github.com/zitadel/zitadel-go](https://github.com/zitadel/zitadel-go)
| .Net | Authentication / Authorization library written in dotnet for the asp.net web application package. | [https://github.com/zitadel/zitadel-net](https://github.com/zitadel/zitadel-net)
| Dart | Dart library for ZITADEL, contains gRPC and API access elements. | [https://github.com/zitadel/zitadel-dart](https://github.com/zitadel/zitadel-dart) |
| Elixir | API Client for the ZITADEL API. | [https://github.com/jshmrtn/zitadel_api](https://github.com/jshmrtn/zitadel_api) |
+324
View File
@@ -0,0 +1,324 @@
---
title: Angular
---
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, 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.
## Setup Application and Get Keys
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, 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.png)
### 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.
> 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.
Continue and create the application.
### 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.
## Angular Setup
Now that you have your web application configured on the ZITADEL side, you can go ahead and integrate your Angular client.
### 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
```
### Create and Configure Auth Module
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',
responseType: 'code',
oidc: true,
clientId: 'YOUR-CLIENT-ID', // replace with your appid
issuer: 'https:/[your-domain]-[random-string].zitadel.cloud', // replace with your instance
redirectUri: 'http://localhost:4200/auth/callback',
postLogoutRedirectUri: 'http://localhost:4200/signedout', // optional
requireHttps: false // required for running locally
};
@NgModule({
...
imports: [
OAuthModule.forRoot(),
HttpClientModule,
...
providers: [
{
provide: 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.
You can use Angular’s schematics to do so:
```bash
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.
```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<boolean> =
new BehaviorSubject(this.authenticated);
constructor(
private oauthService: OAuthService,
private authConfig: AuthConfig,
private statehandler: StatehandlerService
) {}
public get authenticated(): boolean {
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);
return this.authenticated;
}
public signout(): void {
this.oauthService.logOut();
this._authenticated = false;
this._authenticationChanged.next(false);
}
}
```
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
...
const newState = setState ? await this.statehandler.createState().toPromise() : undefined;
...
```
If you decide to use the _StatehandlerService_, provide it in the `app.module`. Make sure it gets initialized first using Angular’s `APP_INITIALIZER`. You find the service implementation in the [example](https://github.com/zitadel/zitadel-examples/tree/main/angular).
```ts
const stateHandlerFn = (stateHandler: StatehandlerService) => {
return () => {
return stateHandler.initStateHandler();
};
};
...
providers: [
{
provide: APP_INITIALIZER,
useFactory: stateHandlerFn,
multi: true,
deps: [StatehandlerService],
},
{
provide: StatehandlerProcessorService,
useClass: StatehandlerProcessorServiceImpl,
},
{
provide: StatehandlerService,
useClass: StatehandlerServiceImpl,
},
]
...
```
### Add Login to Your Application
To log a user in, you need a component or a guard.
- A component could provide a button, starting the login flow on click.
- A guard that starts a login flow once a user without a stored valid access token tries to access a protected route.
Using these components heavily depends on your application. In most cases, you need both.
Generate a component like this:
```bash
ng g component components/login
```
Inject the _AuthenticationService_ and call `authenticate()` on some click event.
Same for the guard:
```bash
ng g guard guards/auth
```
This code shows the _AuthGuard_ used in ZITADEL Console.
```ts
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",
})
export class AuthGuard implements CanActivate {
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();
}
return this.auth.authenticated;
}
}
```
Add the guard to your _RouterModule_ similar to this:
```ts
...
const routes: Routes = [
{
path: '',
loadChildren: () => import('./pages/home/home.module').then(m => m.HomeModule),
canActivate: [AuthGuard],
},
...
```
> 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',
redirectTo: 'user',
},
....
```
### Add Logout to Your Application
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 { AuthenticationService } from "src/app/services/authentication.service";
export class SomeComponentWithLogout {
constructor(private authService: AuthenticationService) {}
public signout(): Promise<void> {
return this.authService.signout();
}
}
```
### Show User 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/authentication.service';
public user$: Observable<any>;
constructor(private auth: AuthenticationService) {
this.user$ = this.auth.getOIDCUser();
}
```
And in your HTML file:
```html
<div *ngIf="user$ | async as user">
<p>{{user | json}}</p>
</div>
```
## Completion
You have successfully integrated your Angular application with ZITADEL!
If you get stuck, consider checking out our [example](https://github.com/zitadel/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/zitadel/zitadel).
![App in console](/img/angular/app-screen.png)
### What's next?
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/zitadel/zitadel) which is using gRPC to access data.
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).
+413
View File
@@ -0,0 +1,413 @@
---
title: Flutter
---
This guide demonstrates how you integrate **ZITADEL** as an idendity provider to a Flutter app.
At the end of the guide you have a mobile application on Android and iOS with the ability
to authenticate users via ZITADEL.
If you need any other information about Flutter, head over to the [documentation](https://flutter.dev/).
## Prerequisites
To move further in this quickstart, you'll need the following things prepared:
- Have Flutter (and Dart) installed ([how-to](https://flutter.dev/docs/get-started/install))
- Have an IDE set up for developing Flutter ([how-to](https://flutter.dev/docs/get-started/editor))
- Create a basic Flutter app ([how-to](https://flutter.dev/docs/get-started/codelab))
- Create a "Native" application in a ZITADEL project
## Flutter with ZITADEL
In your native application on ZITADEL, you need to add a callback (redirect) uri
which matches the selected custom url scheme. As an example, if you intend to
use `ch.myexample.app://sign-me-in` as redirect URI on ZITADEL and in your app,
you need to register the `ch.myexample.app://` custom url scheme within Android and iOS.
:::caution Use Custom Redirect URI!
You'll need the custom redirect url to be compliant with the OAuth 2.0
authentication for mobile devices ([RFC 8252 specification](https://tools.ietf.org/html/rfc8252)).
Otherwise your app might get rejected.
:::
### Hello World
After you created the basic Flutter app, the app will show the following screen:
<div style={{'text-align': 'center', 'margin-bottom': '1rem'}}>
<img src="/img/flutter/hello-world.png" alt="Flutter Hello World" height="500px" />
</div>
You may want to change the Flutter SDK version in `pubspec.yaml` from
```yaml
environment:
sdk: ">=2.7.0 <3.0.0"
```
to
```yaml
environment:
sdk: ">=2.12.0 <3.0.0"
```
With this, you'll enable "nullable by default" mode in Flutter, as well as new language features.
For this quickstart, the minimal Flutter SDK version is set to the default: `sdk: ">=2.7.0 <3.0.0"`.
### Install Dependencies
To authenticate users with ZITADEL in a mobile application, some specific packages are needed.
The [RFC 8252 specification](https://tools.ietf.org/html/rfc8252) defines how
[OAUTH2.0 for mobile and native apps](https://oauth.net/2/native-apps/) works.
Basically, there are two major points in this specification:
1. It recommends to use [PKCE](https://oauth.net/2/pkce/)
2. It does not allow third party apps to open the browser for the login process,
the app must open the login page within the embedded browser view
Install the [`appauth`](https://appauth.io/) package and a secure storage (to store the auth / refresh tokens):
```bash
flutter pub add http
flutter pub add flutter_appauth
flutter pub add flutter_secure_storage
```
#### Important on Android
To use this app auth method on Android 11, you'll need to add a `query` to the `AndroidManifest.xml`.
Go to `<projectRoot>/android/app/src/main/AndroidManifest.xml` and add to the `<manifest>` root:
```xml title="<projectRoot>/android/app/src/main/AndroidManifest.xml"
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.APP_BROWSER" />
<data android:scheme="https" />
</intent>
</queries>
```
This allows the app to query for internal browser activities.
Furthermore, for `secure_storage`, you need to set the minimum SDK version to 18
in `<projectRoot>/android/app/src/build.gradle`. Then, add the manifest placeholder
for your redirect url (the custom url scheme). In the end, the `defaultConfig`
section of the `build.gradle` file should look like this:
```groovy title="<projectRoot>/android/app/src/build.gradle"
defaultConfig {
applicationId "<<YOUR APPLICATION ID, for example ch.myexample.my_fancy_app>>"
minSdkVersion 18
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
manifestPlaceholders = [
'appAuthRedirectScheme': '<<YOUR CUSTOM URL SCHEME, for example ch.myexample.app>>'
]
}
```
#### Important on iOS
In a similar way to Android, you need to register the custom url scheme within iOS to
be able to use custom redirect schemes. In the `Info.plist` file of the Runner
project, you can add the `CFBundleTypeRole` and the `CFBundleUrlSchemes`.
```xml title="<projectRoot>/ios/Runner/Info.plist"
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>YOUR CUSTOM URL SCHEME, for example ch.myexample.app</string>
</array>
</dict>
</array>
```
### Add Authentication
:::note
The auth redirect scheme "`ch.myexample.app`" does register all auth urls with the given
scheme for the app. So an url pointing to `ch.myexample.app://signin` and another one
for `ch.myexample.app://logout` will work with the same registration.
:::
To reduce the commented default code, we will modify the `main.dart` file.
First, the `MyApp` class: it remains a stateless widget:
```dart
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter ZITADEL',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter ZITADEL Quickstart'),
);
}
}
```
Second, the `MyHomePage` class will remain a stateful widget with
its title, we don't change any code here.
```dart
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
```
What we'll change now, is the `_MyHomePageState` class to enable
authentication via ZITADEL and remove the counter button of the hello
world application. We'll show the username of the authenticated user.
We define the needed elements for our state:
```dart
final _appAuth = FlutterAppAuth();
final _secureStorage = const FlutterSecureStorage();
var _busy = false;
var _authenticated = false;
var _username = '';
```
Then the builder method, which does show the login button if you're not
authenticated, a loading bar if the login process is going on and
your name if you are authenticated:
```dart
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (!_authenticated && !_busy)
Text(
'You are not authenticated.',
),
if (!_authenticated && !_busy)
ElevatedButton.icon(
icon: Icon(Icons.fingerprint),
label: Text('login'),
onPressed: _authenticate),
if (_busy)
Stack(
children: [
Center(child: Text("Busy, logging in.")),
Opacity(
opacity: 0.5,
child: Container(
color: Colors.black,
),
),
Center(child: CircularProgressIndicator()),
],
),
if (_authenticated && !_busy)
Text(
'Hello $_username!',
),
],
),
),
);
}
```
And finally the `_authenticate` method which calls the authorization endpoint,
then fetches the user info and stores the tokens into the secure storage.
```dart
Future<void> _authenticate() async {
setState(() {
_busy = true;
});
try {
final result = await _appAuth.authorizeAndExchangeCode(
AuthorizationTokenRequest(
'<<CLIENT_ID>>', // Client ID of the native application
'<<CALLBACK_URL>>', // The registered url from zitadel (e.g. ch.myexample.app://signin)
issuer: '<<ISSUER>>', // most of the cases: https:/[your-domain]-[random-string].zitadel.cloud
scopes: [
'openid',
'profile',
'email',
'offline_access',
],
),
);
final userInfoResponse = await get(
Uri.parse('https://[your-instance].zitadel.cloud/oidc/v1/userinfo'),
headers: {
HttpHeaders.authorizationHeader: 'Bearer ${result.accessToken}',
HttpHeaders.acceptHeader: 'application/json; charset=UTF-8'
},
);
final userJson = jsonDecode(utf8.decode(userInfoResponse.bodyBytes));
await _secureStorage.write(
key: 'auth_access_token', value: result?.accessToken);
await _secureStorage.write(
key: 'refresh_token', value: result?.refreshToken);
await _secureStorage.write(key: 'id_token', value: result?.idToken);
setState(() {
_busy = false;
_authenticated = true;
_username = '${userJson['given_name']} ${userJson['family_name']}';
});
} catch (e, s) {
print('error on authorizeAndExchangeCode token: $e - stack: $s');
setState(() {
_busy = false;
_authenticated = false;
});
}
}
```
Now, you should be able to login with a valid ZITADEL user.
#### Result
In the end, our state class looks like:
```dart
class _MyHomePageState extends State<MyHomePage> {
final _appAuth = FlutterAppAuth();
final _secureStorage = const FlutterSecureStorage();
var _busy = false;
var _authenticated = false;
var _username = '';
Future<void> _authenticate() async {
setState(() {
_busy = true;
});
try {
final result = await _appAuth.authorizeAndExchangeCode(
AuthorizationTokenRequest(
'CLIENT_ID',
'CALLBACK_URL',
issuer: 'ISSUER',
scopes: [
'openid',
'profile',
'email',
'offline_access',
],
),
);
final userInfoResponse = await get(
Uri.parse('https:/[your-domain]-[random-string].zitadel.cloud/oidc/v1/userinfo'), // replace with your instance
headers: {
HttpHeaders.authorizationHeader: 'Bearer ${result.accessToken}',
HttpHeaders.acceptHeader: 'application/json; charset=UTF-8'
},
);
final userJson = jsonDecode(utf8.decode(userInfoResponse.bodyBytes));
await _secureStorage.write(
key: 'auth_access_token', value: result?.accessToken);
await _secureStorage.write(
key: 'refresh_token', value: result?.refreshToken);
await _secureStorage.write(key: 'id_token', value: result?.idToken);
setState(() {
_busy = false;
_authenticated = true;
_username = '${userJson['given_name']} ${userJson['family_name']}';
});
} catch (e, s) {
print('error on authorizeAndExchangeCode token: $e - stack: $s');
setState(() {
_busy = false;
_authenticated = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (!_authenticated && !_busy)
Text(
'You are not authenticated.',
),
if (!_authenticated && !_busy)
ElevatedButton.icon(
icon: Icon(Icons.fingerprint),
label: Text('login'),
onPressed: _authenticate),
if (_busy)
Stack(
children: [
Center(child: Text("Busy, logging in.")),
Opacity(
opacity: 0.5,
child: Container(
color: Colors.black,
),
),
Center(child: CircularProgressIndicator()),
],
),
if (_authenticated && !_busy)
Text(
'Hello $_username!',
),
],
),
),
);
}
}
```
If you run this application, you can authenticate with a valid ZITADEL user.
<div style={{display: 'grid', 'grid-column-gap': '1rem', 'grid-template-columns': '1fr 1fr'}}>
<img src="/img/flutter/not-authed.png" alt="Unauthenticated" height="500px" />
<img src="/img/flutter/authed.png" alt="Flutter Authenticated" height="500px" />
</div>
+163
View File
@@ -0,0 +1,163 @@
---
title: Next.js
---
This is our Zitadel [Next.js](https://nextjs.org/) template. It shows how to authenticate as a user and retrieve user information from the OIDC endpoint.
> The template code is part of our zitadel-example repo. Take a look [here](https://github.com/zitadel/zitadel-examples/tree/main/nextjs).
## Getting Started
First, we start by creating a new NextJS app with `npx create-next-app`, which sets up everything automatically for you. To create a project, run:
```bash
npx create-next-app --typescript
# or
yarn create next-app --typescript
```
# Install Authentication library
To keep the template as easy as possible we use [next-auth](https://next-auth.js.org/) as our main authentication library. To install, run:
```bash
npm i next-auth
# or
yarn add next-auth
```
To run the app, type:
```bash
npm run dev
```
then open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
# Configuration
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`.
```ts
import NextAuth from "next-auth";
export const ZITADEL = {
id: "zitadel",
name: "zitadel",
type: "oauth",
version: "2",
wellKnown: process.env.ZITADEL_ISSUER,
authorization: {
params: {
scope: "openid email profile",
},
},
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({
providers: [ZITADEL],
});
```
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.
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.
Hit Create, then in the detail view of your application make sure to enable dev mode. Dev mode ensures that you can start an auth flow from a non https endpoint for testing.
> Note that we get a clientId but no clientSecret because it is not needed for our authentication flow.
## Environment
Create a file `.env` in the root of the project and add the following keys to it.
```
NEXTAUTH_URL=http://localhost:3000
ZITADEL_CLIENT_ID=[yourClientId]
ZITADEL_ISSUER=https:/[your-domain]-[random-string].zitadel.cloud
```
# User interface
Now we can start editing the homepage by modifying `pages/index.tsx`.
Add this snippet your file. This code gets your auth session from next-auth, renders a Logout button if your authenticated or shows a Signup button if your not.
Note that signIn method requires the id of the provider we provided earlier, and provides a possibilty to add a callback url, Auth Next will redirect you to the specified route if logged in successfully.
```ts
import { signIn, signOut, useSession } from 'next-auth/client';
export default function Page() {
const { data: session } = useSession();
...
{!session && <>
Not signed in <br />
<button onClick={() => signIn('zitadel', { callbackUrl: 'http://localhost:3000/profile' })}>
Sign in
</button>
</>}
{session && <>
Signed in as {session.user.email} <br />
<button onClick={() => signOut()}>Sign out</button>
</>}
...
}
```
### Session state
To allow session state to be shared between pages - which improves performance, reduces network traffic and avoids component state changes while rendering - you can use the NextAuth.js Provider in `/pages/_app.tsx`.
Take a loot at the template `_app.tsx`.
```ts
import { SessionProvider } from "next-auth/react";
function MyApp({ Component, pageProps }) {
return (
<SessionProvider session={pageProps.session}>
<Component {...pageProps} />
</SessionProvider>
);
}
export default MyApp;
```
Last thing: create a `profile.tsx` in /pages which renders the callback page.
```ts
import Link from "next/link";
import styles from "../styles/Home.module.css";
export default function Profile() {
return (
<div className={styles.container}>
<h1>Login successful</h1>
<Link href="/">
<button>Back to Home</button>
</Link>
</div>
);
}
```
+117
View File
@@ -0,0 +1,117 @@
---
title: React
---
This Integration guide shows you the recommended way to integrate **ZITADEL** into your React Application.
It demonstrates how to add a 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.
## Setup Application and get Keys
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 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).
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.
### Redirect URLs
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 app will be deployed to or use `http://localhost:3000/` because this will be the default of npm.
> You should set dev mode to `true` as this will enable unsecure http for the moment.
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.
Continue and Create the application.
### Client ID
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.
## React Setup
### Create React app
Create a new React app with the following command
```bash
npx create-react-app my-app
```
### Install oidc client
You need to install an oauth / oidc client to connect with ZITADEL. Run the following command:
```bash
npm install oidc-react
```
This library helps integrating ZITADEL Authentication in your React Application.
### Create and configure Auth Module
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.
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.
```ts
import React from "react";
import { AuthProvider } from "oidc-react";
import "./App.css";
const oidcConfig = {
onSignIn: async (response: any) => {
alert(
"You logged in :" +
response.profile.given_name +
" " +
response.profile.family_name
);
window.location.hash = "";
},
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() {
return (
<AuthProvider {...oidcConfig}>
<div className="App">
<header className="App-header">
<p>Hello World</p>
</header>
</div>
</AuthProvider>
);
}
export default App;
```
### Run application
Start your react application with the following command
```bash
npm start
```
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 your instance.
After successfully authenticating your user, you will get back to you application.
It should show a popup which says: **You logged in {FirstName} {LastName}**
## Completion
You have successfully integrated ZITADEL in your React Application!
### Whats next?
Now you can proceed implementing our APIs to include Authorization. You can find our API Docs [here](../../apis/introduction)
For more information about creating a React application we refer to [React](https://reactjs.org/docs/getting-started.html) and for more information about the used oauth/oidc library consider reading their docs at [oidc-react](https://www.npmjs.com/package/oidc-react).
+4
View File
@@ -0,0 +1,4 @@
---
title: .NET
---
Coming soon
+150
View File
@@ -0,0 +1,150 @@
---
title: Go
---
This integration guide shows you how to integrate **ZITADEL** into your Go API. It demonstrates how to secure your API using
OAuth 2 Token Introspection.
At the end of the guide you should have an API with a protected endpoint.
## Prerequisites
The client [SDK](https://github.com/zitadel/zitadel-go) will provides an interceptor for both GRPC and HTTP.
This will handle the OAuth 2.0 introspection request including authentication using JWT with Private Key using our [OIDC client library](https://github.com/zitadel/oidc).
All that is required, is an API and its key JSON. But for complete
## Go Setup
### Add Go SDK to your project
You need to add the SDK into Go Modules by:
```bash
go get github.com/zitadel/zitadel-go/v2
```
### Create example API
Create a new go file with the content below. This will create an API with two endpoints. On path `/public` it will always write
back `ok` and the current timestamp. On `/protected` it will respond the same but only if a valid access_token is sent. The token
must not be expired and the API has to be part of the audience (either client_id or project_id).
Make sure to fill the var `issuer` with your own domain. This is the domain of your instance you can find it on the instance detail in the ZITADEL Cloud Customer Portal or in the ZITADEL Console.
```go
package main
import (
"flag"
"log"
"net/http"
"time"
http_mw "github.com/zitadel/zitadel-go/v2/pkg/api/middleware/http"
"github.com/zitadel/zitadel-go/v2/pkg/client/middleware"
)
var (
issuer = flag.String("issuer", "", "issuer of your ZITADEL instance (in the form: https://<instance>.zitadel.cloud or https://<yourdomain>)")
)
func main() {
flag.Parse()
introspection, err := http_mw.NewIntrospectionInterceptor(*issuer, middleware.OSKeyPath())
if err != nil {
log.Fatal(err)
}
router := http.NewServeMux()
router.HandleFunc("/public", writeOK)
router.HandleFunc("/protected", introspection.HandlerFunc(writeOK))
lis := "127.0.0.1:5001"
log.Fatal(http.ListenAndServe(lis, router))
}
func writeOK(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("OK " + time.Now().String()))
}
```
#### Key JSON
To provide the key JSON to the SDK, simply set an environment variable `ZITADEL_KEY_PATH` with the path to the JSON as value.
```bash
export ZITADEL_KEY_PATH=/Users/test/apikey.json
```
For development purposes you should be able to set this in your IDE.
If you're not able to set it via environment variable, you can also exchange the `middleware.OSKeyPath()` and pass it directly:
```go
introspection, err := http_mw.NewIntrospectionInterceptor(
client.Issuer,
"/Users/test/apikey.json",
)
```
### Test API
After you have configured everything correctly, you can simply start the example by:
```bash
go run main.go
```
You can now call the API by browser or curl. Try the public endpoint first:
```bash
curl -i localhost:5001/public
```
it should return something like:
```
HTTP/1.1 200 OK
Date: Tue, 24 Aug 2021 11:11:17 GMT
Content-Length: 59
Content-Type: text/plain; charset=utf-8
OK 2021-08-24 13:11:17.135719 +0200 CEST m=+30704.913892168
```
and the protected:
```bash
curl -i localhost:5001/protected
```
it will return:
```
HTTP/1.1 401 Unauthorized
Content-Type: application/json
Date: Tue, 24 Aug 2021 11:13:10 GMT
Content-Length: 21
"auth header missing"
```
Get a valid access_token for the API. You can achieve this by login into an application of the same project or
by explicitly requesting the project_id for the audience by scope `urn:zitadel:iam:org:project:id:{projectid}:aud`.
If you provide a valid Bearer Token:
```bash
curl -i -H "Authorization: Bearer ${token}" localhost:5001/protected
```
it will return an OK response as well:
```
HTTP/1.1 200 OK
Date: Tue, 24 Aug 2021 11:13:33 GMT
Content-Length: 59
Content-Type: text/plain; charset=utf-8
OK 2021-08-24 13:13:33.131943 +0200 CEST m=+30840.911149251
```