React Academy · leksjon

Credentials Provider og egendefinert innlogging

Autentiser brukere mot en database med en credentials-provider og et egendefinert innloggingsskjema.

Leksjon 3 av 412 trinn

Credentials Provider og egendefinert innlogging er en gratis leksjon i React Academy på CoddyKit. Dette er leksjon 3 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i React Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i React Academy inneholder totalt 4 leksjoner.

Når bør du bruke Credentials Provider

Bruk Credentials-provideren når du autentiserer mot din egen database (e-post + passord) i stedet for en OAuth-leverandør. Det krever nøye håndtering av passord-hashing og sikkerhet.

Definere Credentials Provider

Legg Credentials til i providers-tabellen. authorize-funksjonen mottar de innsendte påloggingsopplysningene og returnerer et brukerobjekt eller null.

import Credentials from 'next-auth/providers/credentials';
import bcrypt from 'bcryptjs';

export const { handlers, auth } = NextAuth({
  providers: [
    Credentials({
      name: 'Credentials',
      credentials: {
        email: { label: 'Email', type: 'email' },
        password: { label: 'Password', type: 'password' },
      },
      async authorize(credentials) {
        const user = await db.user.findUnique({ where: { email: credentials.email as string } });
        if (!user) return null;
        const valid = await bcrypt.compare(credentials.password as string, user.passwordHash);
        if (!valid) return null;
        return { id: user.id, name: user.name, email: user.email };
      },
    }),
  ],
});

Egendefinert innloggingsskjema

Bygg et innloggingsskjema som en Client Component, og kall signIn('credentials', { email, password }) fra next-auth/react.

'use client';
import { signIn } from 'next-auth/react';

export function LoginForm() {
  const [error, setError] = useState('');

  async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    const form = new FormData(e.currentTarget);
    const result = await signIn('credentials', {
      email: form.get('email'),
      password: form.get('password'),
      redirect: false, // handle redirect manually
    });
    if (result?.error) setError('Invalid email or password');
    else router.push('/dashboard');
  }

  return (
    <form onSubmit={handleSubmit}>
      {error && <p className="error">{error}</p>}
      <input name="email" type="email" required />
      <input name="password" type="password" required />
      <button type="submit">Sign in</button>
    </form>
  );
}

redirect: false for feilhåndtering

Send redirect: false til signIn() for å motta resultatobjektet og håndtere feil i komponenten i stedet for å bli omdirigert til en feilside.

const result = await signIn('credentials', { email, password, redirect: false });
if (result?.error) {
  // result.error is 'CredentialsSignin' for auth failures
  setError('Invalid email or password');
}

Zod-validering i authorize

Valider påloggingsopplysningene med Zod inne i authorize-funksjonen før du gjør oppslag i databasen.

import { z } from 'zod';

const schema = z.object({ email: z.string().email(), password: z.string().min(8) });

async authorize(credentials) {
  const parsed = schema.safeParse(credentials);
  if (!parsed.success) return null;
  const { email, password } = parsed.data;
  // ... db lookup
}

Sesjonsstrategi for Credentials

Credentials-provideren krever en JWT-basert sesjonsstrategi (ingen databaseadapter er nødvendig for sesjoner). Angi session: { strategy: 'jwt' } eksplisitt.

export const { handlers, auth } = NextAuth({
  session: { strategy: 'jwt' },
  providers: [Credentials({ ... })],
});

Legge til egendefinerte felt i sesjonen

Send ekstra brukerdata gjennom JWT- og sesjons-callbackene for å gjøre dem tilgjengelige i useSession().

callbacks: {
  async jwt({ token, user }) {
    if (user) { token.id = user.id; token.role = user.role; }
    return token;
  },
  async session({ session, token }) {
    session.user.id = token.id as string;
    session.user.role = token.role as string;
    return session;
  },
},

Hashing av passord

Hash alltid passord med bcrypt før de lagres. Lagre aldri passord i klartekst.

import bcrypt from 'bcryptjs';

// On registration:
const passwordHash = await bcrypt.hash(password, 12);
await db.user.create({ data: { email, passwordHash } });

// On login (in authorize):
const valid = await bcrypt.compare(submittedPassword, user.passwordHash);

Begrense påloggingsforsøk

Beskytt credentials-endepunktet mot brute force ved å begrense antallet påloggingsforsøk med middleware eller et lager i minnet.

// middleware.ts or in a rate-limiting library
import { Ratelimit } from '@upstash/ratelimit';
import { Redis } from '@upstash/redis';

const ratelimit = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(10, '10 s') });

// Check in authorize before DB query:
const { success } = await ratelimit.limit(credentials.email as string);
if (!success) return null;

Registreringsflyt

Registrering er separat fra Auth.js – opprett brukeren i databasen (med hashet passord) via en Server Action eller API-rute, og logg deretter brukeren inn med signIn('credentials', ...).

Hurtigsjekk

Hvorfor bør du sende inn redirect: false når du kaller signIn() i et egendefinert påloggingsskjema?

Oppsummering

Credentials-provideren kaller authorize-funksjonen din med innsendte skjemadata. Valider med Zod, sammenlign hashede passord med bcrypt, og returner et brukerobjekt eller null. Bruk redirect: false i skjemaet for egendefinert feilhåndtering, og bruk alltid JWT-strategi med credentials.

Gratis å komme i gang

Lær deg React med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
88
Leksjoner
324

Ofte stilte spørsmål

Er leksjonen «Credentials Provider og egendefinert innlogging» gratis?

Ja – hele teksten i «Credentials Provider og egendefinert innlogging» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av React Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i React Academy inneholder totalt 4 leksjoner.

Hva lærer jeg i «Credentials Provider og egendefinert innlogging»?

Autentiser brukere mot en database med en credentials-provider og et egendefinert innloggingsskjema. Du øver på React Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med React Academy?

Ingen tidligere erfaring er nødvendig. React Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.

Hvor lang tid tar leksjonen «Credentials Provider og egendefinert innlogging»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne React Academy-leksjonen?

Ja. Alle React Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Sette opp Auth.js i Next.js App Router
  2. Sesjonsadministrasjon og useSession-hooken
  3. Credentials Provider og egendefinert innlogging
  4. Rutebeskyttelse basert på middleware
← Tilbake til React Academy