mirror of
https://github.com/zitadel/zitadel.git
synced 2026-07-25 18:28:00 +00:00
# Which Problems Are Solved Pages in `apps/docs` that embed source from GitHub via the Docusaurus convention ```` ```js reference https://github.com/zitadel/actions/blob/main/examples/org_metadata_claim.js ``` ```` stopped working after the migration from Docusaurus to fumadocs. The old `docusaurus-theme-github-codeblock` plugin used to fetch the file and render it; fumadocs has no support for that meta, so the page rendered the raw URL as plain code-block text. Visible at `/docs/apis/actions/code-examples` and 16 other pages. # How the Problems Are Solved - Converted every ```` ```<lang> reference\n<URL>\n``` ```` block (46 total across 17 `.mdx` files) to the native fumadocs JSX form: `<GithubCodeBlock url="<URL>" />`. The existing `<details>`/`<summary>` collapsibles around blocks are kept — they're an authoring choice, not part of the rendering bug. - Updated `apps/docs/components/github-code-block.tsx` to render via `DynamicCodeBlock` from `fumadocs-ui/components/dynamic-codeblock` (proper shiki highlighting) instead of raw `CodeBlock` + `Pre` (which produced unhighlighted output). Also fixed language detection so a URL hash like `#L10-L20` no longer pollutes the language token. - Registered `GithubCodeBlock` globally in `apps/docs/mdx-components.tsx`, matching how every other shared component (`APIPage`, `Callout`, `Tab/Tabs`, `Step/Steps`, `Admonition`, `TerminologyUpdate`) is exposed. MDX files no longer need a local `import`. # Additional Changes - Normalized the two MDX files that were already using the JSX form (`examples/secure-api/python-django.mdx`, `examples/secure-api/java-spring.mdx`): removed their now-redundant local `import { GithubCodeBlock }` and rewrote 9 long-form `<GithubCodeBlock url="..."></GithubCodeBlock>` tags to self-closing for consistency. # Additional Context Verified locally with `pnpm --filter @zitadel/docs dev`: - `/docs/apis/actions/code-examples` — 20 shiki-highlighted code blocks rendered inside the `<details>` collapsibles (was 0). - `/docs/apis/openidoauth/claims` — line-range hashes (`#L9-L11`) honored. - `/docs/examples/login/flutter` — mixed languages (xml/dart/html) detected and highlighted. - `/docs/guides/integrate/external-audit-log` — edge case of fenced reference indented inside a numbered list also converted and rendered. Greps: - `^[ \t]*\`\`\`[a-zA-Z0-9]+ reference` in `apps/docs/content/**/*.mdx` → 0 matches. - `<GithubCodeBlock url="` in `apps/docs/content/**/*.mdx` → 55 matches. - `from '@/components/github-code-block'` in `apps/docs/content/**/*.mdx` → 0 matches. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
154 lines
5.4 KiB
Plaintext
154 lines
5.4 KiB
Plaintext
---
|
|
title: Secure Django (Python) API Application with ZITADEL
|
|
description: "Integrate ZITADEL with Django Python to validate tokens and check permissions for secure API access using OIDC protocol standards"
|
|
sidebar_label: Django API
|
|
---
|
|
|
|
import AppJWT from '../imports/_app_jwt.mdx';
|
|
import ServiceAccountJWT from '../imports/_serviceaccount_jwt.mdx';
|
|
import ServiceAccountRole from '../imports/_serviceaccount_role.mdx';
|
|
import SetupPython from '../imports/_setup_python.mdx';
|
|
|
|
This integration guide demonstrates the recommended way to incorporate ZITADEL into your Django Python application.
|
|
It explains how to check the token validity in the API and how to check for permissions.
|
|
|
|
By the end of this guide, your application will have three different endpoints that are public, private (valid token) and private-scoped (valid token with a specific role).
|
|
|
|
<Callout>
|
|
This documentation references our [example](https://github.com/zitadel/example-python-django-oauth) on GitHub.
|
|
</Callout>
|
|
|
|
## ZITADEL setup
|
|
|
|
Before we can start building our application, we have to do a few setup steps in the ZITADEL Management Console.
|
|
|
|
### Create application
|
|
|
|
<AppJWT components={props.components} />
|
|
|
|
### Create Service Account
|
|
|
|
<ServiceAccountJWT components={props.components} />
|
|
|
|
### Assign a role to the Service Account
|
|
|
|
<ServiceAccountRole components={props.components} />
|
|
|
|
### Prerequisites
|
|
|
|
At the end you should have the following for the API:
|
|
- Issuer, something like `https://example.zitadel.cloud` or `http://localhost:8080`
|
|
- Introspection URL, something like `https://example.zitadel.cloud/oauth/v2/introspect`
|
|
- Token URL, something like `https://example.zitadel.cloud/oauth/v2/token`
|
|
- `.json`-key-file for the API, from the application
|
|
- ID of the project
|
|
|
|
And the following from the Service Account:
|
|
- `.json`-key-file from the service account
|
|
|
|
## Setup new Django application
|
|
|
|
### Setup Python
|
|
|
|
<SetupPython components={props.components} />
|
|
|
|
### Install dependencies
|
|
|
|
For this example we need the following dependencies:
|
|
- `django`: to create an API with django
|
|
- `python-dotenv`: to use environment variables in the settings
|
|
- `authlib`: client-side OAuth functionality
|
|
- `requests`: HTTP requests for the introspection
|
|
|
|
For the dependencies we need a requirements.txt-file with the following content:
|
|
|
|
<GithubCodeBlock url="https://github.com/zitadel/example-python-django-oauth/blob/main/requirements.txt" />
|
|
|
|
Then install all dependencies with:
|
|
```bash
|
|
python -m pip install -U requirements.txt
|
|
```
|
|
|
|
Then in your folder of choice, call the following command to create a Django base:
|
|
```bash
|
|
django-admin startproject myapi .
|
|
```
|
|
|
|
## Define the Django API
|
|
|
|
### Add to the settings.py to include ZITADEL info
|
|
|
|
There is info needed for the introspection calls, which we put into the settings.py:
|
|
|
|
<GithubCodeBlock url="https://github.com/zitadel/example-python-django-oauth/blob/main/myapi/settings.py#L125-L133" />
|
|
|
|
and create a ".env"-file in the root folder with the settings as an example:
|
|
```bash
|
|
ZITADEL_INTROSPECTION_URL = 'URL to the introspection endpoint to verify the provided token'
|
|
ZITADEL_DOMAIN = 'Domain used as audience in the token verification'
|
|
API_PRIVATE_KEY_FILE_PATH = 'Path to the key.json created in ZITADEL'
|
|
```
|
|
|
|
I should look something like this:
|
|
|
|
```bash
|
|
ZITADEL_INTROSPECTION_URL = 'https://example.zitadel.cloud/oauth/v2/introspect'
|
|
ZITADEL_DOMAIN = 'https://example.zitadel.cloud'
|
|
API_PRIVATE_KEY_FILE_PATH = '/tmp/example/250719519163548112.json'
|
|
```
|
|
|
|
### Validator definition
|
|
|
|
To validate the tokens, we need a validator which can be called in the event of API-calls.
|
|
|
|
validator.py:
|
|
<GithubCodeBlock url="https://github.com/zitadel/example-python-django-oauth/blob/main/myapi/validator.py" />
|
|
|
|
### Requests and URLs
|
|
|
|
We define 3 different endpoints which differ in terms of requirements.
|
|
views.py:
|
|
<GithubCodeBlock url="https://github.com/zitadel/example-python-django-oauth/blob/main/myapi/views.py" />
|
|
|
|
To handle endpoints the urls have to be added to the urls.py:
|
|
<GithubCodeBlock url="https://github.com/zitadel/example-python-django-oauth/blob/main/myapi/urls.py" />
|
|
|
|
### DB
|
|
|
|
Create and run migrations:
|
|
|
|
```bash
|
|
python manage.py migrate
|
|
```
|
|
|
|
### Run
|
|
|
|
You can use a local Django server to test the application.
|
|
|
|
```bash
|
|
python manage.py runserver
|
|
```
|
|
|
|
### Call the API
|
|
|
|
To call the API you need an access token, which is then verified by ZITADEL.
|
|
Please follow [this guide here](/guides/integrate/token-introspection/private-key-jwt), ignoring the first step as we already have the `.json`-key-file from the serviceaccount.
|
|
|
|
Optionally set the token as an environment variable:
|
|
```
|
|
export TOKEN='MtjHodGy4zxKylDOhg6kW90WeEQs2q...'
|
|
```
|
|
|
|
With the access token, you can then do the following calls:
|
|
```
|
|
curl -H "Authorization: Bearer $TOKEN" -X GET http://localhost:8000/api/public
|
|
curl -H "Authorization: Bearer $TOKEN" -X GET http://localhost:8000/api/private
|
|
curl -H "Authorization: Bearer $TOKEN" -X GET http://localhost:8000/api/private-scoped
|
|
```
|
|
|
|
## Completion
|
|
|
|
Congratulations! You have successfully integrated your Django API with ZITADEL!
|
|
|
|
If you get stuck, consider checking out our [example](https://github.com/zitadel/example-python-django-oauth) application. This application includes all the functionalities mentioned in this quick-start. You can start by cloning the repository and defining the settings in the settings.py. If you face issues, contact us or raise an issue on [GitHub](https://github.com/zitadel/example-python-django-oauth/issues).
|