Log ind med Dazr Identity: udviklerdokumentation
Standard OpenID Connect 1.0 med authorization code-forløbet og PKCE. Ingen SDK nødvendig: ethvert certificeret OpenID Connect-bibliotek virker, og det gør almindelig kode også.
Folk kan allerede bruge deres Google- eller Microsoft-konto i Dazr Identity, så din app behøver ikke separate Google- og Microsoft-knapper ved siden af: én knap i stedet for tre.
Discovery og endpoints
Alt er beskrevet i discovery-dokumentet. Peg dit bibliotek mod udstederen, så finder det resten.
| Hvad | Adresse |
|---|---|
| Udsteder (issuer) | https://identity.dazr.eu |
| Discovery | https://identity.dazr.eu/.well-known/openid-configuration |
| Autorisation | https://identity.dazr.eu/oauth/authorize |
| Token | https://identity.dazr.eu/oauth/token |
| Brugeroplysninger | https://identity.dazr.eu/oauth/userinfo |
| Offentlige nøgler (JWKS) | https://identity.dazr.eu/oauth/jwks |
| Tilbagekaldelse (RFC 7009) | https://identity.dazr.eu/oauth/revoke |
| Introspektion (RFC 7662), kun webserverapps | https://identity.dazr.eu/oauth/introspect |
| Log ud (RP-initiated logout) | https://identity.dazr.eu/oauth/logout |
| Verifikationsrapporter, kun webserverapps | https://identity.dazr.eu/oauth/verification-report |
Registrér en app
- Apps tilhører en organisation. Ejere og administratorer af organisationen registrerer dem under Udviklere.
- Webserverapps (fortrolige klienter) får en klienthemmelighed, der vises én gang. Godkend over for token-endpointet med HTTP Basic (
client_secret_basic) eller i formularens body (client_secret_post). - Single-page- og mobilapps (offentlige klienter) får ingen hemmelighed. De sender
client_idog bruger PKCE. - Omdirigerings-URI'er skal matche præcist. De skal være
https://. Mens appen er i test, virkerhttp://localhostoghttp://127.0.0.1på enhver port også. - En adresse til privatlivspolitikken, en support-e-mail og et formål på én linje er påkrævet: folk ser dem på samtykkeskærmen.

Integrationsguides
Hver stack nedenfor bruger sin egen standardunderstøttelse af OpenID Connect. Du skal bruge tre værdier fra konsollen: klient-id'et, klienthemmeligheden (kun webserverapps) og den omdirigerings-URI, du registrerede. Resten kommer fra discovery-dokumentet.
- Auth.js / NextAuth
- Next.js App Router
- WordPress
- Laravel
- Supabase
- Django
- Node.js (openid-client)
- Ethvert OpenID Connect-bibliotek
sub er parvist: det samme for alle apps i din organisation, forskelligt for alle andre organisationer. Det ændres aldrig for en person, mens en e-mailadresse kan ændres. Gem sub som kontonøgle, og behandl email som kontaktdata.
Auth.js / NextAuth
Auth.js (NextAuth.js v5) tager et brugerdefineret OpenID Connect-providerobjekt. Registrér en webserverapp, sæt AUTH_SECRET, AUTH_DAZR_ID og AUTH_DAZR_SECRET, og brug denne callback-URL som omdirigerings-URI: https://app.example.eu/api/auth/callback/dazr.
// auth.ts
import NextAuth from "next-auth"
export const { handlers, auth, signIn, signOut } = NextAuth({
providers: [
{
id: "dazr",
name: "Dazr Identity",
type: "oidc",
issuer: "https://identity.dazr.eu",
clientId: process.env.AUTH_DAZR_ID,
clientSecret: process.env.AUTH_DAZR_SECRET,
authorization: { params: { scope: "openid profile email" } },
checks: ["pkce", "state", "nonce"],
client: { id_token_signed_response_alg: "ES256" },
},
],
})
NextAuth.js v4 bruger samme idé med type: "oauth" og discovery-URL'en:
// pages/api/auth/[...nextauth].ts (NextAuth.js v4), in providers: [ ... ]
{
id: "dazr",
name: "Dazr Identity",
type: "oauth",
wellKnown: "https://identity.dazr.eu/.well-known/openid-configuration",
clientId: process.env.DAZR_CLIENT_ID,
clientSecret: process.env.DAZR_CLIENT_SECRET,
authorization: { params: { scope: "openid profile email" } },
idToken: true,
checks: ["pkce", "state"],
client: { id_token_signed_response_alg: "ES256" },
profile(profile) {
return { id: profile.sub, name: profile.name ?? null, email: profile.email }
},
}
Next.js App Router
Med filen auth.ts ovenfor tilføjer du route-handleren og en login-knap, der kører en server action.
// app/api/auth/[...nextauth]/route.ts
import { handlers } from "@/auth"
export const { GET, POST } = handlers
// app/page.tsx
import { auth, signIn, signOut } from "@/auth"
export default async function Page() {
const session = await auth()
if (session?.user) {
return (
<form action={async () => { "use server"; await signOut() }}>
<p>Signed in as {session.user.email}</p>
<button type="submit">Sign out</button>
</form>
)
}
return (
<form action={async () => { "use server"; await signIn("dazr") }}>
<button type="submit" className="dazr-signin">Sign in with Dazr Identity</button>
</form>
)
}
Style knappen som vist under Knappen. I callbacks er Dazrs sub lig med account.providerAccountId.
WordPress
Brug et generisk OpenID Connect-klientplugin, f.eks. OpenID Connect Generic Client. Registrér en webserverapp, og udfyld pluginets indstillinger med værdierne nedenfor. Pluginet viser den omdirigerings-URI, der skal registreres, på sin indstillingsside; som standard er den https://example.com/wp-admin/admin-ajax.php?action=openid-connect-authorize.
| Indstilling | Værdi |
|---|---|
| Klient-id | dit klient-id |
| Klienthemmelighed | din klienthemmelighed |
| Scope | openid profile email |
| Login-endpoint (autorisation) | https://identity.dazr.eu/oauth/authorize |
| Token-endpoint | https://identity.dazr.eu/oauth/token |
| Endpoint for brugeroplysninger | https://identity.dazr.eu/oauth/userinfo |
| Endpoint for afslutning af session | https://identity.dazr.eu/oauth/logout |
| Identitetsnøgle | sub |
| PKCE | til (S256) |
Navnene på indstillingerne varierer lidt mellem plugins. Har et plugin ingen PKCE-mulighed, så vælg et andet: Dazr Identity afviser logins uden PKCE.
Laravel
Laravel Socialite har ingen indbygget generisk OpenID Connect-driver, så tilføj en lille brugerdefineret driver. Den sender folk til Dazr med PKCE og læser brugeren fra endpointet for brugeroplysninger. Socialite læser ikke discovery-dokumentet, så endpoints er skrevet ud. Registrér en webserverapp med omdirigerings-URI'en https://app.example.eu/auth/dazr/callback.
<?php
// app/Socialite/DazrProvider.php
namespace App\Socialite;
use Laravel\Socialite\Two\AbstractProvider;
use Laravel\Socialite\Two\User;
class DazrProvider extends AbstractProvider
{
protected $scopes = ['openid', 'profile', 'email'];
protected $scopeSeparator = ' ';
protected $usesPKCE = true;
protected function getAuthUrl($state)
{
return $this->buildAuthUrlFromBase('https://identity.dazr.eu/oauth/authorize', $state);
}
protected function getTokenUrl()
{
return 'https://identity.dazr.eu/oauth/token';
}
protected function getUserByToken($token)
{
$response = $this->getHttpClient()->get('https://identity.dazr.eu/oauth/userinfo', [
'headers' => ['Authorization' => 'Bearer '.$token],
]);
return json_decode((string) $response->getBody(), true);
}
protected function mapUserToObject(array $user)
{
return (new User)->setRaw($user)->map([
'id' => $user['sub'],
'name' => $user['name'] ?? null,
'email' => $user['email'] ?? null,
]);
}
}
// config/services.php
'dazr' => [
'client_id' => env('DAZR_CLIENT_ID'),
'client_secret' => env('DAZR_CLIENT_SECRET'),
'redirect' => env('DAZR_REDIRECT_URI'),
],
// app/Providers/AppServiceProvider.php, in boot()
use Laravel\Socialite\Facades\Socialite;
use App\Socialite\DazrProvider;
Socialite::extend('dazr', function ($app) {
return Socialite::buildProvider(DazrProvider::class, config('services.dazr'));
});
// routes/web.php
Route::get('/auth/dazr', fn () => Socialite::driver('dazr')->redirect());
Route::get('/auth/dazr/callback', function () {
$dazr = Socialite::driver('dazr')->user();
$user = \App\Models\User::updateOrCreate(
['dazr_sub' => $dazr->getId()],
['name' => $dazr->getName() ?? $dazr->getEmail(), 'email' => $dazr->getEmail()],
);
Auth::login($user);
return redirect('/');
});
Supabase
Supabase Auth har ingen generisk OpenID Connect-provider, du kan pege mod en hvilken som helst udsteder: dens loginproviders og integrationer med tredjeparts-auth er faste lister. Så du kan ikke tilføje Dazr Identity i Supabase-dashboardet i dag. Hvis Supabase tilføjer generisk understøttelse af OpenID Connect, så brug værdierne fra tjeklisten nedenfor.
Alternativet: log folk ind med Dazr Identity på din egen server (med en af guiderne på denne side), gem Dazrs sub i din brugertabel, og tal med Supabase fra den server med service role-nøglen, mens du tjekker adgang i din egen kode. Send aldrig service role-nøglen til en browser.
Django
Brug mozilla-django-oidc. Registrér en webserverapp med omdirigerings-URI'en https://app.example.eu/oidc/callback/. Biblioteket læser ikke discovery-dokumentet, så endpoints er skrevet ud.
# settings.py
import os
INSTALLED_APPS += ["mozilla_django_oidc"] # after django.contrib.auth
AUTHENTICATION_BACKENDS = [
"mozilla_django_oidc.auth.OIDCAuthenticationBackend",
"django.contrib.auth.backends.ModelBackend",
]
OIDC_RP_CLIENT_ID = os.environ["DAZR_CLIENT_ID"]
OIDC_RP_CLIENT_SECRET = os.environ["DAZR_CLIENT_SECRET"]
OIDC_RP_SCOPES = "openid profile email"
OIDC_RP_SIGN_ALGO = "ES256"
OIDC_OP_JWKS_ENDPOINT = "https://identity.dazr.eu/oauth/jwks"
OIDC_OP_AUTHORIZATION_ENDPOINT = "https://identity.dazr.eu/oauth/authorize"
OIDC_OP_TOKEN_ENDPOINT = "https://identity.dazr.eu/oauth/token"
OIDC_OP_USER_ENDPOINT = "https://identity.dazr.eu/oauth/userinfo"
OIDC_USE_PKCE = True
OIDC_PKCE_CODE_CHALLENGE_METHOD = "S256"
LOGIN_REDIRECT_URL = "/"
LOGOUT_REDIRECT_URL = "/"
# urls.py
from django.urls import include, path
urlpatterns += [path("oidc/", include("mozilla_django_oidc.urls"))]
# template: start the sign-in
# <a href="{% url 'oidc_authentication_init' %}">Sign in with Dazr Identity</a>
Som standard matcher backenden brugere efter e-mail. For at bruge sub som kontonøgle laver du en underklasse af OIDCAuthenticationBackend og overskriver filter_users_by_claims og create_user. Brug en aktuel version: ældre versioner kan ikke verificere ES256-signaturer.
Node.js (openid-client)
openid-client (version 6) læser discovery-dokumentet og tjekker PKCE, state, nonce og ID-tokenet for dig.
import * as client from 'openid-client';
const config = await client.discovery(
new URL('https://identity.dazr.eu'),
process.env.DAZR_CLIENT_ID,
process.env.DAZR_CLIENT_SECRET, // public client: pass undefined here and client.None() as the 4th argument
);
const redirect_uri = 'https://app.example.eu/auth/dazr/callback';
// 1. Start: keep the three random values in the user's session.
export async function start(session) {
session.verifier = client.randomPKCECodeVerifier();
session.state = client.randomState();
session.nonce = client.randomNonce();
return client.buildAuthorizationUrl(config, {
redirect_uri,
scope: 'openid profile email',
code_challenge: await client.calculatePKCECodeChallenge(session.verifier),
code_challenge_method: 'S256',
state: session.state,
nonce: session.nonce,
});
}
// 2. Callback: pass the full callback URL (a URL object).
export async function callback(session, currentUrl) {
const tokens = await client.authorizationCodeGrant(config, currentUrl, {
pkceCodeVerifier: session.verifier,
expectedState: session.state,
expectedNonce: session.nonce,
});
const claims = tokens.claims(); // sub, email, name
return { sub: claims.sub, email: claims.email, name: claims.name };
}
Ethvert OpenID Connect-bibliotek
Står din stack ikke på listen, virker enhver OpenID Connect-klient. Tjek disse indstillinger:
- Udsteder
https://identity.dazr.eu, discovery-URLhttps://identity.dazr.eu/.well-known/openid-configuration. - Response type
code(authorization code-forløb). Intet implicit eller hybrid forløb. - PKCE er påkrævet, med
code_challenge_method=S256. - Scopes:
openidplus kun det, du har brug for, afprofile,email,address,organisationsogoffline_access. Din app skal være registreret til hvert scope, den beder om. - Omdirigerings-URI: præcis som registreret i konsollen, inklusive stien og eventuel query string.
- Klientgodkendelse:
client_secret_basicellerclient_secret_postfor webserverapps,nonefor single-page- og mobilapps. - Signatur på ID-tokenet: ES256. Nogle biblioteker antager RS256: sæt algoritmen til ES256.
- Brug
subsom kontonøgle. Den er parvis, pr. organisation. - Med
offline_accessskal du gemme det nye refresh token efter hver fornyelse: de roterer.
Forløbet
- Opret en tilfældig
code_verifier(43 til 128 tegn) og denscode_challenge= base64url(SHA-256(verifier)). Opret en tilfældigstateognonce. Gem alle tre i brugerens session. - Omdirigér til authorization-endpointet med
response_type=code,client_id,redirect_uri,scope(altid inklusiveopenid),state,nonce,code_challengeogcode_challenge_method=S256. - Personen logger ind, hvis det er nødvendigt, og ser samtykkeskærmen med de faktiske data. Når personen tillader det, kommer vedkommende tilbage til din omdirigerings-URI med
code,stateogiss. Tjek, atstatematcher, og atisserhttps://identity.dazr.eu. - På din server laver du en POST til token-endpointet med
grant_type=authorization_code,code, den sammeredirect_uriogcode_verifier. - Verificér ID-tokenet: ES256-signatur med en nøgle fra JWKS (match
kid),iss,aud= dit klient-id,expog dinnonce. Brugsubsom kontonøgle.

Parameteren prompt accepterer none (svar med det samme med login_required eller consent_required, hvis personen skulle handle), login (bed personen logge ind igen) og consent (vis samtykkeskærmen, selv når den er godkendt før). max_age understøttes. Husket samtykke: hvis personen har godkendt de samme scopes før, går vedkommende direkte tilbage til din app. Beder du om mere senere, viser samtykkeskærmen kun det nye.
Scopes og claims
Bed kun om det, du har brug for. Intet uden for denne tabel findes: ingen kontakter, ingen filer, ingen adgangskoder.
| Scope | Claims |
|---|---|
openid (påkrævet) | sub: et tilfældigt id for personen, det samme for alle apps i din organisation og forskelligt for alle andre organisationer |
profile | name (hvis angivet) og locale |
email | email og email_verified (altid true) |
address | address (formatted, street_address, locality, region, postal_code, country), kun hvis personen har gemt en |
organisations | organisations: de organisationer, personen markerer på samtykkeskærmen, hver med id, name, display_name, website, country, register_number, vat, vat_verified (kun true, når EU's VIES-tjeneste har bekræftet momsnummeret), verified, verification (se Verificerede organisationer) og role (owner, admin eller member) |
offline_access | ingen claims; du modtager også et refresh token |
Claims vises i ID-tokenet for de scopes, personen godkendte. Endpointet for brugeroplysninger returnerer det samme sæt med aktuelle værdier.
Verificerede organisationer
Dazr verificerer kun en organisation, når officielle kilder beviser to ting: hvem personen er, og at personen repræsenterer denne organisation, med dens navn, registreringsnummer og momsnummer. Typisk underskriver direktøren en kort erklæring med en kvalificeret elektronisk signatur (QES) og tilføjer udskriften fra virksomhedsregistret, der nævner vedkommende; med en udskrift forseglet af registret, som den italienske visura eller en hollandsk KvK-udskrift, sker det øjeblikkeligt, ellers gennemgår Dazr den. En kvalificeret signatur alene gør aldrig en organisation verificeret. Hver organisation i claimet organisations har sin aktuelle verifikation:

| verification.status | Betydning |
|---|---|
unverified | Ikke verificeret, eller en verifikation mislykkedes, udløb eller blev tilbagekaldt (f.eks. efter at det juridiske navn eller virksomhedsnummeret ændrede sig). |
pending | Verifikationen er i gang: repræsentanten er blevet bedt om at underskrive, udskriften fra virksomhedsregistret mangler stadig, eller Dazr gennemgår dokumenter. method angiver, hvilken vej der blev startet, f.eks. qes (repræsentanten underskriver erklæringen), qseal, pec, letter, video eller documents. |
verified | Verificeret. method er qes_org (kvalificeret signatur, certifikatet nævner organisationen), extract_sealed (kvalificeret signatur eller gennemgået ID plus en udskrift forseglet af virksomhedsregistret), qes_reviewed (kvalificeret signatur, udskrift tjekket af Dazr), qseal (organisationens kvalificerede elektroniske segl), documents, pec (en kode sendt til organisationens PEC-adresse, Italien), letter (en kode sendt med posten til det registrerede hjemsted), video (et videoopkald med Dazr) eller extract. authority angiver, hvad der beviste, at personen repræsenterer organisationen (se nedenfor), og verified_at er et Unix-tidspunkt. |
Kun når status er verified, angiver verification.authority (og authority i webhooks), hvordan forbindelsen mellem personen og organisationen blev bevist:
| verification.authority | Betydning |
|---|---|
certificate | Underskriverens kvalificerede certifikat eller organisationens kvalificerede segl nævner organisationen med dens registreringsnummer. Med kun et momsnummer i certifikatet beviste en registerudskrift registreringsnummeret. |
register_extract | En udskrift forseglet af virksomhedsregistret, højst 3 måneder gammel, nævner organisationen med dens registrerings- og momsnummer og angiver underskriveren som direktør eller juridisk repræsentant. |
reviewed | Dazr tjekkede en udskrift, der nævner underskriveren, eller, uden kvalificeret signatur, udskriften og et ID. |
pec | En kode sendt til PEC-adressen på visuraen forseglet af registret (Italien). |
letter | En kode sendt med posten til det registrerede hjemsted, efter at Dazr havde tjekket oplysningerne mod registret. |
video | Et videoopkald med Dazr: et ID og en officiel udskrift, der nævner personen. |
Booleanen verified bevares af kompatibilitetshensyn og er lig med verification.status === 'verified'. Hver organisation har også et id, det samme, som webhooks bruger.
Når status er pending eller verified, er verification.report_url adressen på dens verifikationsrapport.
"organisations": [{
"id": "org_3k9x2m0q8w1v5t7a", "name": "Conti Logistica S.r.l.", "country": "IT",
"register_number": "REA MI1234567", "vat": "IT12345678903", "vat_verified": true,
"display_name": "Conti", "website": "https://conti.example",
"verified": false, "verification": { "status": "pending", "method": "qes" }, "role": "owner"
}]
role og medlemskab læses igen ved hver fornyelse af token og hver anmodning om brugeroplysninger: efter en rolleændring har næste svar den nye rolle, og en organisation, personen har forladt eller er fjernet fra, er ikke længere med. Når en administrator af organisationen afbryder din app, udelades organisationen af tidligere udstedte tokens, indtil et medlem deler den med din app igen ved et nyt login. display_name og website er null, når organisationen ikke har angivet dem; name er altid det juridiske navn.
Kræv en verificeret organisation
Sæt i konsollen Kræv en verificeret organisation til Verifikation startet eller Verificeret, eller bed om det pr. anmodning med acr_values=urn:dazr:org:verification-started eller acr_values=urn:dazr:org:verified (den strengeste af de to vinder). Din app skal også anmode om scopet organisations.

En person uden en kvalificerende organisation tages gennem det i samme login: navnet, organisationen (med momsnummeret tjekket i VIES) og derefter verifikationen. Personen kan underskrive med det samme, få erklæringen sendt til sig selv via e-mail eller angive en anden, der underskriver. Derefter markerer personen organisationen på samtykkeskærmen (kun kvalificerende organisationer kan markeres) og vender tilbage til din omdirigerings-URI.
Skal en anden stadig underskrive, kommer personen tilbage med status pending, også når du bad om Verificeret: du modtager en kode, claimet siger pending, og ID-tokenets acr er urn:dazr:org:verification-started i stedet for urn:dazr:org:verified. Styr altid adgang efter verification.status, aldrig efter, at login lykkedes. Med prompt=none får du interaction_required, når kravet ikke er opfyldt.
Ændringer af indstillingen gælder fra næste login. Folk, der allerede er logget ind, logges ikke ud: svar på fornyelser, endpointet for brugeroplysninger og webhooks har altid den aktuelle status, så brug dem til at reagere for eksisterende sessioner.
Webhooks
Tilføj en webhook-URL (https) i konsollen. Du ser signeringshemmeligheden én gang; du kan rotere den. Dazr sender organisation.verification.updated, når en organisation, som en af dine brugere har delt med din app, bliver pending, verified, failed eller unverified. Apps, der aldrig har modtaget en organisation via samtykke, hører aldrig om det.
POST /your/webhook
Content-Type: application/json
Dazr-Event: organisation.verification.updated
Dazr-Delivery: dlv_8Fq2…
Dazr-Signature: t=1791021600,v1=5e0c…
{ "id": "evt_…", "type": "organisation.verification.updated", "created": 1791021600,
"data": { "organisation": { "id": "org_3k9x2m0q8w1v5t7a", "name": "Conti Logistica S.r.l.", "country": "IT" },
"status": "verified", "method": "qes_org", "authority": "certificate", "verified_at": 1791021598,
"report_url": "https://identity.dazr.eu/oauth/verification-report?org=org_3k9x2m0q8w1v5t7a",
"subjects": ["Xo1c…"] } }
status er pending, verified, failed eller unverified. subjects er sub-værdierne i din app for de personer, der har delt denne organisation med den. Tjek signaturen, før du stoler på body'en:
import crypto from 'node:crypto';
// raw = the request body exactly as received (a string), header = the Dazr-Signature header
function verifyDazrSignature(raw, header, secret) {
const m = /^t=(\d+),v1=([a-f0-9]{64})$/.exec(header || '');
if (!m || Math.abs(Date.now() / 1000 - Number(m[1])) > 300) return false; // reject old deliveries
const want = crypto.createHmac('sha256', secret).update(m[1] + '.' + raw).digest('hex');
return crypto.timingSafeEqual(Buffer.from(want), Buffer.from(m[2]));
}
Svar med en hvilken som helst 2xx inden for 8 sekunder. Ellers prøver Dazr igen efter cirka 5 minutter, 30 minutter, 2, 6, 12 og 24 timer og markerer derefter leveringen som mislykket. Hvert forsøg har samme Dazr-Delivery-id, så ignorér dubletter. Konsollen viser de seneste leveringer, kan sende en igen og kan sende en testhændelse (webhook.test). Polling af endpointet for brugeroplysninger virker også.
Verifikationsrapporter til revisioner
For hver organisation, der er delt med din app, kan du hente en rapport om, hvordan og hvornår Dazr verificerede den, til din revisionssag. Den findes, mens organisationen er verificeret, og mens verifikationen er i gang, og viser så det, der er gjort indtil videre.
- Organisationen: navn, land, registreringsnummer, momsnummer og registreret hjemsted.
- Verifikationen: status, metode, bemyndigelse, og hvornår den blev anmodet om, underskrevet og verificeret.
- Dokumentationen: for en kvalificeret signatur eller et kvalificeret segl underskriverens navn som på certifikatet, certifikatets udsteder, serienummer, gyldighed og SHA-256-fingeraftryk, dets kvalificerede status (QC-erklæringer, tillidstjenesteudbyder og tjeneste fra EU's tillidsliste, med listens løbenummer og udstedelsesdato), signeringstidspunktet og tjekket for tilbagekaldelse. For en registerforseglet udskrift hvem der forseglede den, hvornår, og hvad der matchede: navn, registreringsnummer, momsnummer, direktør. VIES-resultatet. For en PEC-kode, et brev eller et videoopkald datoerne og de tjek, en gennemgangsperson hos Dazr markerede, vist som "Gennemgangsperson hos Dazr" med et internt id.
- Til dine sager: SHA-256-fingeraftrykket af hver dokumentationsfil, et dokument-id, hvornår rapporten blev genereret, og en kort forklaring af hver metode og af, hvad bemyndigelse betyder.
En rapport indeholder aldrig billeder eller numre fra identitetsdokumenter, engangskoder, PEC-adressen, e-mailadresser eller andre adresser end det registrerede hjemsted.
Hent en rapport
Godkend med dit klient-id og din klienthemmelighed, som ved token-endpointet: HTTP Basic (client_secret_basic) eller formularens body i en POST (client_secret_post). Sæt aldrig hemmeligheden i URL'en. Brug organisationens id fra claims eller webhooks, eller blot den verification.report_url, de indeholder.
curl -u "$DAZR_CLIENT_ID:$DAZR_CLIENT_SECRET" -o report.pdf \
"https://identity.dazr.eu/oauth/verification-report?org=org_3k9x2m0q8w1v5t7a&format=pdf&lang=en"
| Parameter | Betydning |
|---|---|
org | Organisationens id. |
format | pdf (standard) eller jws, de samme fakta som signeret JSON. |
lang | PDF'ens sprog: en (standard), nl, it, de, fr, es eller pl. |
doc | I stedet for rapporten: declaration, direktørens signerede erklæring (kun kvalificeret signatur eller segl), eller extract, udskriften fra virksomhedsregistret. |
Kun organisationer, som mindst én af dine brugere har delt med din app via samtykke, kan hentes. Enhver anden organisation svarer 404, ligesom en, der ikke findes eller ikke har nogen verifikation; en forkert klienthemmelighed svarer 401. Apps uden klienthemmelighed kan ikke hente rapporter. Downloads er hastighedsbegrænsede, og hver download vises i organisationens aktivitet for dens administratorer med din apps navn. I konsollen viser din apps side de forbundne organisationer med de samme downloads.
Verificér den signerede JSON
Med format=jws modtager du en kompakt JWS (ES256, header typ dazr-verification-report+jwt), signeret med de samme nøgler som ID-tokens. Dens claims er iss, iat, jti (dokument-id'et), sub (organisationens id), aud (dit klient-id) og report, fakta. PDF'en indeholder den samme JWS på sidste side og i sine metadata (DazrVerificationReport), så en PDF også kan tjekkes offline.
import { createRemoteJWKSet, jwtVerify } from 'jose';
const jwks = createRemoteJWKSet(new URL('https://identity.dazr.eu/oauth/jwks'));
// jws = the response body of format=jws, or the text from the PDF metadata
const { payload } = await jwtVerify(jws, jwks, {
issuer: 'https://identity.dazr.eu',
audience: process.env.DAZR_CLIENT_ID,
typ: 'dazr-verification-report+jwt',
});
console.log(payload.report.verification.status, payload.report.verification.authority);
Lad en revisor tjekke signaturen
For en kvalificeret signatur eller et kvalificeret segl returnerer doc=declaration den signerede erklæring præcis, som den blev uploadet: en signeret PDF (PAdES) eller en .p7m-fil (CAdES). En revisor kan validere den uafhængigt med Europa-Kommissionens DSS-demovalidator: upload filen, behold standardpolitikken for validering, og kør den. Resultatet viser, om signaturen er kvalificeret (QESig, eller QESeal for et segl), hvem der underskrev, og tillidstjenesteudbyderen fra EU's tillidsliste. doc=extract returnerer udskriften fra virksomhedsregistret; en registerforseglet udskrift kan valideres på samme måde.
Rapporten er dokumentation til din revisionssag. Regulerede virksomheder er fortsat ansvarlige for deres egne kundekendskabsprocedurer.
Dazr opbevarer den signerede erklæring, udskriften og rapportdataene, mens organisationen er verificeret, og i 5 år efter at dens verifikation ophører, eller organisationen slettes. Opbevar dine egne kopier, så længe dine regler kræver det.
Tokens og levetider
| Token | Levetid og regler |
|---|---|
| Autorisationskode | 60 sekunder, engangsbrug, bundet til din klient, omdirigerings-URI og PKCE-challenge. Bruges en kode to gange, tilbagekaldes de tokens, den udstedte. |
| Access token | 10 minutter. En signeret JWT (ES256, typ at+jwt) med aud = dit klient-id. Send den som Authorization: Bearer. |
| ID-token | 10 minutter. ES256, med iss, sub, aud, exp, iat, auth_time, nonce og amr, hvor kendt. |
| Refresh token | Kun med offline_access. Roterer ved hver brug: gem altid det nye. Sendes et gammelt refresh token igen, tilbagekaldes hele loginet. Udløber efter 30 dage uden brug og højst efter 180 dage. |
Signeringsnøgler roterer. Vælg altid nøglen efter kid fra JWKS, og opdatér JWKS, når du ser et ukendt kid.
Fejl
Så længe dit klient-id og din omdirigerings-URI er gyldige, kommer fejl tilbage til din omdirigerings-URI som error, error_description, state og iss: f.eks. invalid_request (som manglende eller plain PKCE), invalid_scope, unsupported_response_type, access_denied (personen annullerede, eller appen er i test, og personen er ikke medlem), login_required, consent_required og interaction_required (med prompt=none, når en påkrævet verificeret organisation mangler). Med en ukendt klient eller en ikke-registreret omdirigerings-URI viser Dazr en fejlside og omdirigerer aldrig. Token-endpointet svarer med JSON-fejl som invalid_client, invalid_grant og unsupported_grant_type.
Log ud
For at logge en person ud sender du vedkommende til logout-endpointet med id_token_hint (eller client_id), en valgfri post_logout_redirect_uri, der er registreret i din apps indstillinger, og state. Dazr spørger, om personen også vil logge ud af Dazr Identity på den enhed, og sender vedkommende derefter tilbage. Tilbagekald refresh tokens, du ikke længere har brug for, ved revocation-endpointet.
Test og go-live
En ny app er i test: kun medlemmer af din organisation kan logge ind, og det står på samtykkeskærmen. For at gå live skal du få din organisation verificeret i Dazr Identity, tilføje en https://-omdirigerings-URI og anmode om en live-gennemgang i konsollen. Ændring af navn, formål, privatlivspolitik eller data for en live app kræver en ny gennemgang.
Overfør en app til en anden organisation
En app kan flyttes til en anden organisation, der er registreret hos Dazr, f.eks. efter et salg eller en omorganisering. En ejer eller administrator starter overførslen under Overfør app i appens indstillinger, i Dazr Identity eller i Sign-portalen. En ejer eller administrator af den anden organisation accepterer eller afviser den inden for 14 dage. Indtil da kan afsenderen annullere, og intet ændres.
- Hvem der kan modtage den. Kun en organisation registreret hos Dazr, angivet med dens organisations-id. Dens ejere og administratorer finder id'et i dens juridiske oplysninger i Dazr Identity. En live app, en app til gennemgang, en app, der kræver en verificeret organisation, og en app med Dazr Sign API slået til kan kun flyttes til en verificeret organisation. Det tjekkes igen, når overførslen accepteres.
- Et nyligt login. At starte og acceptere en overførsel kræver et login inden for de seneste 10 minutter.
- Hvad der flyttes. Klient-id'et, indstillingerne, logoet, omdirigerings-URI'erne, de aktiverede API'er og webhook-URL'erne. Den administrator, der accepterer, accepterer også Udviklervilkårene for den nye organisation.
- Klienthemmeligheden. En webserverapp får en ny klienthemmelighed, der vises én gang for den administrator, der accepterer. Den tidligere hemmelighed virker fortsat ved token-, revocation- og introspection-endpointene i den overgangsperiode, der blev valgt, da overførslen startede: ingen, 24 timer (standard) eller 7 dage. Verifikationsrapporter kræver den nye hemmelighed.
- Webhooks. URL'erne bliver. Deres signeringshemmeligheder, for Dazr Identity og for Dazr Sign, fornyes og vises én gang for den administrator, der accepterer. Leveringer fra før overførslen sendes ikke igen.
- Personer og deres
sub. Hver person beholder sammesubi appen, så kontiene i din app fortsat virker. Den adskiller sig fra personenssubi den nye organisations andre apps. Folk godkender appen igen ved næste login, fordi samtykkeskærmen nu nævner den nye organisation. Tokens udstedt før overførslen holder op med at virke. - Hvad der bliver hos den tidligere ejer. Antal logins og samtykker og webhook-leveringer fra før overførslen. Dokumenter oprettet via Dazr Sign API bliver hos de personer, der ejer dem, og appens nye ejer kan ikke se dem.
Knappen
Brug formuleringen "Log ind med Dazr Identity" og Dazr-logoet som nedenfor. Du må ændre størrelsen, ikke logoet, farverne eller formuleringen. Link den til din egen route, der starter forløbet.
<a href="/auth/dazr" style="display:inline-flex;align-items:center;gap:10px;height:44px;padding:0 18px;border-radius:22px;background:#18203a;color:#fff;font: 600 15px/1 'Dazr', system-ui, sans-serif;text-decoration:none">
<svg width="20" height="20" viewBox="0 0 100 100" aria-hidden="true"><path d="M50 4 89 16v31c0 25.5-16.8 42.5-39 50C27.8 89.5 11 72.5 11 47V16z" fill="#fff"/><path d="M50 15.5 79 24.5v22.8c0 19.5-12.4 32.6-29 38.7C33.4 79.9 21 66.8 21 47.3V24.5z" fill="#18203a"/><path d="M50 24 71 30.6v16.9c0 14.5-9 24.4-21 29.2-12-4.8-21-14.7-21-29.2V30.6z" fill="#fff"/></svg>
Sign in with Dazr Identity
</a>
Dazr-skrifttypen. Knappen bruger Dazr-skrifttypen, som er gratis at bruge under SIL Open Font License. Hvor Dazr ikke er indlæst, bruges systemskrifttypen i stedet. Download Dazr-skrifttypen (ZIP med TTF- og WOFF2-filer) for at hoste den på dit eget website:
/* woff2 files from the ZIP, copied to /fonts/ on your site */
@font-face { font-family: 'Dazr'; font-weight: 400; font-display: swap;
src: url('/fonts/dazr-regular-latin.woff2') format('woff2'); }
@font-face { font-family: 'Dazr'; font-weight: 700; font-display: swap;
src: url('/fonts/dazr-bold-latin.woff2') format('woff2'); }
.dazr-signin { font: 600 15px/1 'Dazr', system-ui, sans-serif; }
Et minimalt Node.js-eksempel
Node 18 eller nyere, ingen afhængigheder. En webserverapp med klienthemmelighed; for en offentlig klient fjerner du Authorization-headeren og sender client_id i body'en.
import crypto from 'node:crypto';
const issuer = 'https://identity.dazr.eu';
const clientId = process.env.DAZR_CLIENT_ID;
const clientSecret = process.env.DAZR_CLIENT_SECRET;
const redirectUri = 'https://app.example.eu/auth/dazr/callback';
const b64url = (buf) => Buffer.from(buf).toString('base64url');
// 1. Start: keep verifier, state and nonce in the user's session.
export function start(session) {
session.verifier = b64url(crypto.randomBytes(32));
session.state = b64url(crypto.randomBytes(16));
session.nonce = b64url(crypto.randomBytes(16));
const challenge = b64url(crypto.createHash('sha256').update(session.verifier).digest());
return issuer + '/oauth/authorize?' + new URLSearchParams({
response_type: 'code', client_id: clientId, redirect_uri: redirectUri,
scope: 'openid profile email', state: session.state, nonce: session.nonce,
code_challenge: challenge, code_challenge_method: 'S256',
});
}
// 2. Callback: check state, exchange the code, verify the ID token.
export async function callback(session, query) {
if (query.error) throw new Error('sign-in failed: ' + query.error);
if (query.state !== session.state || query.iss !== issuer) throw new Error('state or issuer mismatch');
const res = await fetch(issuer + '/oauth/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: 'Basic ' + Buffer.from(clientId + ':' + clientSecret).toString('base64'),
},
body: new URLSearchParams({ grant_type: 'authorization_code', code: query.code, redirect_uri: redirectUri, code_verifier: session.verifier }),
});
const tokens = await res.json();
if (!res.ok) throw new Error(tokens.error);
const claims = await verifyIdToken(tokens.id_token, session.nonce);
return { sub: claims.sub, email: claims.email, name: claims.name, tokens };
}
async function verifyIdToken(idToken, nonce) {
const [h, p, s] = idToken.split('.');
const header = JSON.parse(Buffer.from(h, 'base64url'));
const { keys } = await (await fetch(issuer + '/oauth/jwks')).json();
const jwk = keys.find((k) => k.kid === header.kid);
if (!jwk || header.alg !== 'ES256') throw new Error('unknown signing key');
const ok = crypto.verify('sha256', Buffer.from(h + '.' + p),
{ key: crypto.createPublicKey({ key: jwk, format: 'jwk' }), dsaEncoding: 'ieee-p1363' }, Buffer.from(s, 'base64url'));
const c = JSON.parse(Buffer.from(p, 'base64url'));
const now = Math.floor(Date.now() / 1000);
if (!ok || c.iss !== issuer || c.aud !== clientId || c.exp < now - 30 || c.nonce !== nonce) throw new Error('invalid ID token');
return c;
}
Grænser
Authorization- og token-endpointene er hastighedsbegrænsede. Får du HTTP 429, så vent og prøv igen; prøv ikke igen i en tæt løkke.
Dine forpligtelser
Din organisation er selvstændig dataansvarlig for de data, den modtager. Udviklervilkårene for Dazr Identity fastlægger, hvad du må gøre med dem, hvordan du holder dem sikre, og hvordan du indberetter brud. Spørgsmål: hello@dazr.eu.