</>
APIGuiden.se
Säkerhet11 min2026-03-02

API-autentisering: OAuth 2.0, API-nycklar och JWT i praktiken

Jämförelse av autentiseringsmetoder för API:er. Lär dig välja rätt approach för ditt projekt och implementera säker tokenhantering.

OAuthJWTAPI KeysSäkerhet

Överblick av autentiseringsmetoder

Det finns tre dominerande metoder för API-autentisering, och valet beror på användningsfallet. API-nycklar är enklast att implementera och passar server-till-server-kommunikation. JWT (JSON Web Tokens) fungerar bra för autentisering i egna applikationer. OAuth 2.0 är standard när du behöver tredjepartsåtkomst eller delegerad auktorisering.

Varje metod har styrkor och svagheter. API-nycklar är enkla men ger ingen granulär kontroll. JWT är flexibelt men kräver noggrann hantering av tokenlivstid. OAuth 2.0 är mest komplett men också mest komplext att implementera korrekt.

auth-comparison.ts
typescript
// Tre autentiseringsmetoder jämförda

// 1. API-nyckel (enklast, server-to-server)
fetch("/api/data", {
  headers: {
    "X-API-Key": "sk_live_abc123def456"
  }
});

// 2. JWT Bearer Token (egna appar)
fetch("/api/data", {
  headers: {
    "Authorization": "Bearer eyJhbGciOiJIUzI1NiIs..."
  }
});

// 3. OAuth 2.0 (tredjepartsåtkomst)
fetch("/api/data", {
  headers: {
    "Authorization": "Bearer ya29.access-token-from-oauth"
  }
});

OAuth 2.0 Authorization Code Flow

OAuth 2.0 Authorization Code Flow är den rekommenderade metoden för webbapplikationer som behöver åtkomst till en användares data hos en tredje part. Flödet sker i flera steg: klienten skickar användaren till tjänstens inloggning, användaren godkänner åtkomst, tjänsten redirectar tillbaka med en authorization code, och klienten byter ut koden mot access- och refresh-tokens.

Använd alltid PKCE (Proof Key for Code Exchange) för att skydda mot authorization code interception-attacker, oavsett om klienten är konfidentiell eller publik.

auth/oauth.ts
typescript
// OAuth 2.0 med PKCE i Next.js
import crypto from "crypto";

// Steg 1: Generera PKCE-parametrar
function generatePKCE() {
  const verifier = crypto.randomBytes(32)
    .toString("base64url");
  const challenge = crypto
    .createHash("sha256")
    .update(verifier)
    .digest("base64url");
  return { verifier, challenge };
}

// Steg 2: Redirecta till OAuth-provider
export async function GET(req: Request) {
  const { verifier, challenge } = generatePKCE();

  const authUrl = new URL("https://provider.com/oauth/authorize");
  authUrl.searchParams.set("client_id", process.env.CLIENT_ID!);
  authUrl.searchParams.set("redirect_uri", "https://app.se/callback");
  authUrl.searchParams.set("response_type", "code");
  authUrl.searchParams.set("scope", "read write");
  authUrl.searchParams.set("code_challenge", challenge);
  authUrl.searchParams.set("code_challenge_method", "S256");

  return Response.redirect(authUrl.toString());
}

// Steg 3: Byt authorization code mot tokens
export async function handleCallback(
  code: string,
  verifier: string
) {
  const response = await fetch("https://provider.com/oauth/token", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      grant_type: "authorization_code",
      client_id: process.env.CLIENT_ID,
      client_secret: process.env.CLIENT_SECRET,
      code,
      redirect_uri: "https://app.se/callback",
      code_verifier: verifier,
    }),
  });

  const { access_token, refresh_token } = await response.json();
  return { access_token, refresh_token };
}

Säker tokenhantering

Tokens är nyckeln till ditt API och måste hanteras med omsorg. Access tokens bör ha kort livstid (15-60 minuter) och refresh tokens längre (dagar till veckor). Spara aldrig tokens i localStorage (sårbart för XSS) - använd httpOnly-cookies eller säker serverside-lagring.

Implementera token-rotation: varje gång en refresh token används, utfärda en ny. Om en gammal refresh token används igen har den troligtvis stulits, och alla tokens för den användaren bör ogiltigförklaras omedelbart.

auth/tokens.ts
typescript
// Säker tokenhantering med rotation
import jwt from "jsonwebtoken";

interface TokenPair {
  accessToken: string;
  refreshToken: string;
}

async function generateTokenPair(
  userId: string
): Promise<TokenPair> {
  // Kort livstid för access token
  const accessToken = jwt.sign(
    { sub: userId, type: "access" },
    process.env.JWT_SECRET!,
    { expiresIn: "15m" }
  );

  // Längre livstid + rotation
  const refreshToken = jwt.sign(
    { sub: userId, type: "refresh", jti: crypto.randomUUID() },
    process.env.JWT_REFRESH_SECRET!,
    { expiresIn: "7d" }
  );

  // Spara refresh token hash i databasen
  await db.refreshTokens.create({
    data: {
      userId,
      tokenHash: crypto
        .createHash("sha256")
        .update(refreshToken)
        .digest("hex"),
      expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
    },
  });

  return { accessToken, refreshToken };
}

Letar du efter pålitlig hosting för dina API-projekt?

Kolla in mehosting.com