Synthèse automatique
Fournit des instructions pour intégrer l'authentification Hanko dans une application web avec Docker Compose, Next.js et Phoenix.
Points forts
- Solution auto-hébergée offrant un contrôle total sur les données utilisateur
- Prend en charge WebAuthn (passkeys), mots de passe et codes
- Sessions basées sur JWT avec vérification JWKS
- Architecture claire pour l'intégration frontend et backend
Limites
- Nécessite une configuration minutieuse en production (HTTPS, cookies sécurisés)
- Limitée à la pile technologique spécifique (Next.js, Phoenix)
- Hanko Cloud peut être nécessaire pour OAuth tiers et domaines personnalisés
Lorsque vous avez besoin d'un système d'authentification auto-hébergé compatible avec les passkeys pour une application web avec un frontend JavaScript et une API backend.
Lorsque vous avez besoin de fournisseurs OAuth prêts à l'emploi ou préférez un service d'authentification entièrement géré comme Auth0 ou Firebase.
Analyse de sécurité
SûrThe skill is a static reference document with no executable commands or destructive actions. It contains no secrets, no obfuscated payloads, and no instructions that could compromise a system if followed.
Aucun point d'attention détecté
Comment cette analyse est faiteExemples
I want to self-host Hanko authentication using Docker Compose. Show me the configuration for public and admin APIs, WebAuthn, session, and secrets.How do I add Hanko login and registration to my Next.js app using @teamhanko/hanko-elements? Include setup for web components and events.Write a Next.js middleware that verifies the Hanko JWT using JWKS from the Hanko API.Hanko Auth — Project Skill Reference
Self-hosted Hanko (ghcr.io/teamhanko/hanko:latest) via Docker Compose.
Public API: :8000, Admin API: :8001.
Frontend env var: NEXT_PUBLIC_HANKO_API_URL=http://localhost:8000.
Backend env var: HANKO_API_URL=http://hanko:8000 (internal Docker network).
Architecture
Browser
├── <hanko-auth /> web component → Hanko :8000 (login / register)
├── Cookie "hanko" (JWT, httpOnly, SameSite=Lax)
├── Next.js middleware → verifies JWT via JWKS
└── API calls to Phoenix :4000 → Bearer <jwt>
Phoenix
├── AuthPlug → verify JWT with JwksCache (ETS, 5 min TTL)
└── LoadCurrentUserPlug → find_or_create user by hanko_id (sub claim)
Hanko Config (hanko/config.yaml)
server:
public: { address: ":8000", cors: { allow_origins: ["http://localhost:3000"], allow_credentials: true } }
admin: { address: ":8001" }
webauthn:
relying_party: { id: "localhost", display_name: "Repousse", origins: ["http://localhost:3000"] }
session:
lifespan: "1h"
enable_auth_token_header: true # also sends token as X-Auth-Token header
cookie: { http_only: true, same_site: "lax", secure: false } # secure: true in prod
password: { enabled: true, min_length: 8 }
passcode: { ttl: 120 }
secrets:
keys: ["<32-char-secret>"] # rotate via array; first key used to sign
Production checklist:
secure: trueon cookieallow_origins→ real domainrelying_party.id+origins→ real domainwebauthn.relying_party.originsmust include protocol+host (no trailing slash)- Custom domain in Hanko Cloud (if Cloud) fixes 3rd-party OAuth + cookie scoping
Frontend (@teamhanko/hanko-elements)
Installation
npm install @teamhanko/hanko-elements @teamhanko/hanko-frontend-sdk
Register components (client component)
"use client";
import { register } from "@teamhanko/hanko-elements";
const HANKO_API_URL = process.env.NEXT_PUBLIC_HANKO_API_URL!;
useEffect(() => { register(HANKO_API_URL).catch(console.error); }, []);
Web components
<hanko-auth /> {/* combined login + registration */}
<hanko-login /> {/* login only */}
<hanko-registration /> {/* registration only */}
<hanko-profile /> {/* credential management */}
TypeScript — add to src/custom.d.ts:
declare module "react" {
namespace JSX {
interface IntrinsicElements {
"hanko-auth": HankoAuthElementProps;
"hanko-profile": HankoProfileElementProps;
"hanko-events": HankoEventsElementProps;
}
}
}
Events
// DOM event (used in this project)
document.addEventListener("hankoAuthSuccess", handler);
// SDK event
import { Hanko } from "@teamhanko/hanko-frontend-sdk";
const hanko = new Hanko(HANKO_API_URL);
hanko.onSessionCreated(() => router.push("/dashboard"));
Register options
register(url, {
shadow: true, // default true — shadow DOM
injectStyles: true, // default true
enablePasskeys: true, // default true
sessionCheckInterval: 3000, // ms minimum
sessionTokenLocation: "cookie", // "cookie" | "sessionStorage"
cookieDomain: "example.com",
cookieSameSite: "lax",
fallbackLanguage: "fr",
});
Frontend SDK (@teamhanko/hanko-frontend-sdk)
import { Hanko } from "@teamhanko/hanko-frontend-sdk";
const hanko = new Hanko(HANKO_API_URL);
// Current user
const user = await hanko.user.getCurrent();
// { id, email, ... }
// Logout
await hanko.user.logout();
Logout pattern (this project)
// lib/auth.ts
export async function logout() {
const hanko = getHanko();
await hanko.user.logout();
}
Next.js Middleware (JWT via JWKS)
Cookie name: hanko — contains a signed JWT (RS256).
// middleware.ts
import { jwtVerify, createRemoteJWKSet } from "jose";
const JWKS = createRemoteJWKSet(
new URL(`${HANKO_API_URL}/.well-known/jwks.json`)
);
const token = request.cookies.get("hanko")?.value;
await jwtVerify(token, JWKS); // throws on invalid/expired
JWKS endpoint: GET {HANKO_API_URL}/.well-known/jwks.json
Public paths in this project: ["/", "/auth/login", "/auth/register", "/api/webhooks"]
Matcher (excludes Next.js internals):
export const config = {
matcher: ["/((?!_next/static|_next/image|favicon.ico|.*\\.svg).*)"],
};
Phoenix/Elixir — JWT Validation
Flow
- Frontend sends
Authorization: Bearer <jwt>on all API calls AuthPlugextracts token, callsJwksCache.get_keys/0, verifies viaJoken- On success:
conn.assigns.hanko_claims=%{"sub" => hanko_user_id, "exp" => ..., "email" => ...} LoadCurrentUserPlugfinds or createsRepousse.Accounts.Userbyhanko_idconn.assigns.current_useravailable in controllers
JWT claims
%{
"sub" => "uuid-string", # Hanko user ID — used as hanko_id FK
"email" => "user@ex.com", # present on first login
"exp" => 1234567890, # unix timestamp
"iss" => "http://localhost:8000"
}
JwksCache (Repousse.Auth.JwksCache)
- GenServer, ETS table
:hanko_jwks - Refreshes every 5 min
- Config:
Application.get_env(:repousse, :hanko)[:jwks_url]→ should behttp://hanko:8000/.well-known/jwks.json(internal Docker URL) - Start in
application.exsupervision tree
Router pipeline
pipeline :authenticated do
plug RepousseWeb.Plugs.AuthPlug
plug RepousseWeb.Plugs.LoadCurrentUserPlug
end
pipeline :admin do
plug RepousseWeb.Plugs.RequireRolePlug, role: :admin
end
Alternative: POST /sessions/validate (simpler, no JWT lib)
# Not used in this project but available:
Req.post("#{hanko_url}/sessions/validate",
json: %{session_token: token}
)
# Response: %{"is_valid" => true, "user_id" => "..."}
Hanko Admin API (:8001)
No auth required from same network (internal only — never expose to internet).
Key endpoints
GET /users # list users (supports ?email=, ?page=, ?per_page=)
POST /users # create user
GET /users/:id # get user by Hanko ID
DELETE /users/:id # delete user
PATCH /users/:id # update user
GET /users/:id/credentials # list credentials (passkeys, passwords, OTPs)
DELETE /users/:id/credentials/:cred_id
GET /users/:id/emails # list emails
POST /users/:id/emails # add email
DELETE /users/:id/emails/:email_id
POST /users/:id/emails/:email_id/set_primary
GET /users/:id/sessions # active sessions
DELETE /users/:id/sessions/:session_id # revoke session
GET /audit_logs # audit trail
GET /webhooks # list configured webhooks
POST /webhooks # create webhook
Usage from Elixir (internal Docker network):
base = Application.get_env(:repousse, :hanko)[:admin_url]
# e.g. http://hanko:8001
Req.get("#{base}/users/#{hanko_id}")
Req.delete("#{base}/users/#{hanko_id}")
Webhooks
Requires Pro/Enterprise plan on Hanko Cloud. Self-hosted: configure in config.yaml.
Payload structure
{
"event": "user.login",
"token": "<JWT — decode to get data>"
}
JWT payload (after decode + JWKS verify):
{
"sub": "hanko webhooks",
"evt": "user.login",
"data": { /* full user object */ },
"iat": 1234567890,
"exp": 1234567890,
"aud": ["..."]
}
Event types
user.create # new registration
user.delete # account deleted
user.login # authentication event
user.update.email.create # email added
user.update.email.delete # email removed
user.update.email.primary # primary email changed
user.update.password.update
user.update.username.create / .delete / .update
Verification (Phoenix)
# 1. Fetch JWKS from {HANKO_API_URL}/.well-known/jwks.json
# 2. Verify token with JWKS (same JwksCache can be reused)
# 3. Decode payload → extract data.evt + data.data
# 4. Return 200 within 30 seconds
Passkey API (separate product — not used in this project)
Use only if adding passkeys to an existing auth system (not replacing it). This project uses full Hanko (auth + user management), so Passkey API is not relevant.
If ever needed:
- Hanko Cloud → create "Passkey API" project type
- Two endpoint tiers: frontend (no secret) for login, backend (secret key) for registration
- JS SDK:
@teamhanko/passkeys-sdk
Common Gotchas
| Problem | Cause | Fix |
|---------|-------|-----|
| Cookie not sent to Phoenix | Authorization: Bearer not set | Frontend must read cookie and send as header |
| JWKS fetch fails | Wrong URL in JwksCache config | Use Docker-internal URL http://hanko:8000 not localhost |
| WebAuthn fails locally | relying_party.id mismatch | Must match origin hostname exactly |
| Session not created event | Using wrong event name | DOM: hankoAuthSuccess, SDK: onSessionCreated |
| CORS error on login | Missing allow_credentials: true | Set in hanko/config.yaml + Phoenix CORSPlug |
| Token expired (1h) | Default lifespan | Extend in config or implement refresh |
| Admin API 404 | Wrong port | Admin is :8001, Public is :8000 |
| Passkey not offered | enablePasskeys: false | Remove option or set to true |
Relevant Files (this project)
| File | Purpose |
|------|---------|
| hanko/config.yaml | Hanko server config |
| docker-compose.yml | Hanko service + env vars |
| frontend/src/middleware.ts | Next.js route protection (JWKS verify) |
| frontend/src/lib/auth.ts | Hanko SDK singleton + logout |
| frontend/src/app/(main)/auth/login/page.tsx | <hanko-auth /> component + post-login redirect |
| backend/lib/repousse/auth/jwks_cache.ex | ETS-cached JWKS keys, 5 min refresh |
| backend/lib/repousse_web/plugs/auth_plug.ex | JWT verification via Joken |
| backend/lib/repousse_web/plugs/load_current_user_plug.ex | Hanko ID → DB user |
| backend/lib/repousse_web/router.ex | Pipeline composition |
Du fichier au premier essai
Le téléchargement contient exactement le contenu affiché sur cette fiche. Cette copie peut différer de la dernière version du dépôt source.
Consulter la source et ses fichiers annexesCe téléchargement contient uniquement SKILL.md. Les scripts, références, modèles et dépendances éventuels ne sont pas inclus. Récupérez les fichiers nécessaires depuis la source en conservant leur arborescence avant de poursuivre.
1. Télécharger le fichier
Télécharger SKILL.mdDepuis la racine d’un projet de test, enregistrez le fichier sous .skill-downloads/hanko-auth-integration-reference-mryiqibf/SKILL.md, ou utilisez la commande suivante. Ce dossier sert à examiner la skill avant son installation.
Commande pour macOS/Linux ou WSL : un shell POSIX et curl sont nécessaires. Sous Windows sans WSL, utilisez le bouton de téléchargement et créez le dossier manuellement.
mkdir -p '.skill-downloads/hanko-auth-integration-reference-mryiqibf' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/hanko-auth-integration-reference-mryiqibf/download' --output '.skill-downloads/hanko-auth-integration-reference-mryiqibf/SKILL.md.part' && mv '.skill-downloads/hanko-auth-integration-reference-mryiqibf/SKILL.md.part' '.skill-downloads/hanko-auth-integration-reference-mryiqibf/SKILL.md'2. Vérifier les prérequis
Lisez SKILL.md avant de l’utiliser. Si le fichier cite des scripts ou services externes, examinez-les et préparez les accès nécessaires dans votre environnement de test.
Extrait original : Installation
npm install @teamhanko/hanko-elements @teamhanko/hanko-frontend-sdk
Les plateformes de la fiche sont des indications du catalogue. Les chemins ci-dessous suivent la documentation des outils ; ils ne prouvent pas que cette skill y a été exécutée. Aucune version minimale de ces outils n’est attestée pour cette fiche.
3. Charger la skill
Le fichier ne fournit pas un en-tête name/description exploitable pour cette procédure native. Le téléchargement reste disponible pour lecture ; utilisez le mode manuel ci-dessous.
Mode manuel ou autre outil : joignez SKILL.md à une conversation, ou ouvrez-le dans un agent capable de lire les fichiers. Ajoutez les ressources annexes nécessaires. Il n’existe pas de dossier universel reconnu par tous les outils.
4. Faire un premier essai
Utilisez une entrée courte et fictive : un endpoint d’API, un petit document ou un brief d’interface. Dans une nouvelle conversation, joignez le fichier ou donnez son chemin à l’agent, puis adaptez cette demande :
Lis .skill-downloads/hanko-auth-integration-reference-mryiqibf/SKILL.md et applique ses instructions à cet exemple : [décrire une entrée de test]. Indique les fichiers, dépendances ou accès qui manquent. Produis le résultat demandé par la skill sans inventer de données ni exécuter de script non examiné.Résultat attendu : une sortie correspondant aux instructions de la skill, ou une liste précise des prérequis manquants. Une simple confirmation de lecture ne valide pas le premier usage. Si une ressource externe est indisponible, ce parcours reste à tester.
Sécurité AMM DeFi
Securite
Checklist de sécurité pour les contrats Solidity AMM, pools de liquidité et flux de swap. Couvre réentrance, attaques par donation, manipulation d'oracles, etc.
Créateur de règles Semgrep
Securite
Crée des règles Semgrep personnalisées pour détecter des vulnérabilités de sécurité, des motifs de bugs et des motifs de code. Inclut une méthodologie de test en premier, le support du mode taint et des étapes de validation. Utile pour construire des détections d'analyse statique ciblées.
Revue barre d'outils développement
Securite
Règles de sécurité pour la barre d'outils de développement, le client PostHog et les feature flags. À utiliser lors de la revue de modifications des composants dev-tools et connexes.