Get the Hanko API URL

Retrieve the API URL from the Hanko console.

If you are self-hosting Hanko you need to provide your own URL.

Hanko Authentication with JWT

Upon a successful login, Hanko sends a cookie containing a JSON Web Token (JWT). You can use this JWT to authenticate requests on your backend.

Steps to Authenticate Requests

  1. Retrieve the JSON Web Key Set (JWKS): The JWKS has the public keys to verify the JWT. Fetch it from the Hanko API’s .well-known/jwks.json endpoint.

  2. Verify the JWT: Use the JWKS to verify the JWT.

Deno-based Backend Example

In the following example, we demonstrate how to implement a custom middleware in a Fresh app using jose packages.

import { MiddlewareHandlerContext } from "$fresh/server.ts";
import { getCookies } from "$std/http/cookie.ts";
import * as jose from "";

interface AuthState {
  auth: jose.JWTPayload;

const JWKS_ENDPOINT = `${Deno.env.get("HANKO_API_URL")}/.well-known/jwks.json`;

const JWKS = jose.createRemoteJWKSet(new URL(JWKS_ENDPOINT), {
  cooldownDuration: 120000,

function getToken(req: Request): string | undefined {
  const cookies = getCookies(req.headers);
  const authorization = req.headers.get("authorization");

  if (authorization && authorization.split(" ")[0] === "Bearer")
    return authorization.split(" ")[1];
  else if (cookies.hanko) return cookies.hanko;

export async function handler(
  req: Request,
  ctx: MiddlewareHandlerContext<AuthState>
) {
  const jwt = getToken(req);

  if (jwt) {
    try {
      const { payload } = await jose.jwtVerify(jwt, JWKS);
      ctx.state.auth = payload;

      return await;
    } catch (error) {
      return new Response("Invalid token", { status: 403 });

  return new Response("Missing token", { status: 403 });