Dostawca Credentials i niestandardowe logowanie
Uwierzytelnianie użytkowników względem bazy danych za pomocą dostawcy credentials i niestandardowego formularza logowania.
Dostawca Credentials i niestandardowe logowanie to bezpłatna lekcja React Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej React Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs React Academy zawiera 4 lekcji w sumie.
Kiedy używać Credentials Provider
Użyj Credentials Provider, gdy uwierzytelniasz użytkowników za pomocą własnej bazy danych (adres e-mail + hasło), a nie dostawcy OAuth. Wymaga to starannego obsługiwania haszowania haseł i kwestii bezpieczeństwa.
Definiowanie Credentials Provider
Dodaj Credentials do tablicy dostawców. Funkcja authorize otrzymuje przesłane dane logowania i zwraca obiekt użytkownika albo 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 };
},
}),
],
});Niestandardowy formularz logowania
Zbuduj formularz logowania jako Client Component, który wywołuje signIn('credentials', { email, password }) z 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 przy obsłudze błędów
Przekaż redirect: false do signIn(), aby otrzymać obiekt wyniku i obsłużyć błędy w komponencie zamiast przekierowywać użytkownika na stronę błędu.
const result = await signIn('credentials', { email, password, redirect: false });
if (result?.error) {
// result.error is 'CredentialsSignin' for auth failures
setError('Invalid email or password');
}Walidacja Zod w authorize
Sprawdzaj poprawność danych logowania za pomocą Zod wewnątrz funkcji authorize, zanim odwołasz się do bazy danych.
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
}Strategia sesji dla danych logowania
Provider danych logowania wymaga strategii sesji JWT (adapter bazy danych nie jest potrzebny do obsługi sesji). Należy jawnie ustawić session: { strategy: 'jwt' }.
export const { handlers, auth } = NextAuth({
session: { strategy: 'jwt' },
providers: [Credentials({ ... })],
});Dodawanie niestandardowych pól do sesji
Dodatkowe dane użytkownika należy przekazywać za pośrednictwem callbacków JWT i sesji, aby udostępnić je w 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;
},
},Haszowanie haseł
Przed zapisaniem hasła należy zawsze haszować za pomocą bcrypt. Nigdy nie należy przechowywać haseł w postaci jawnego tekstu.
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);Ograniczanie częstotliwości prób logowania
Należy chronić endpoint danych logowania przed atakami siłowymi, ograniczając częstotliwość prób logowania za pomocą middleware lub magazynu w pamięci.
// 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;Proces rejestracji
Rejestracja jest oddzielona od Auth.js — użytkownika należy utworzyć w bazie danych (z hasłem poddanym haszowaniu) za pomocą Server Action lub trasy API, a następnie zalogować go za pomocą signIn('credentials', ...).
Szybkie sprawdzenie
Dlaczego podczas wywoływania signIn() w niestandardowym formularzu logowania należy przekazać redirect: false?
Podsumowanie
Provider danych logowania wywołuje funkcję authorize z przesłanymi danymi formularza. Należy przeprowadzić walidację za pomocą Zod, porównać hasła poddane haszowaniu za pomocą bcrypt i zwrócić obiekt użytkownika albo null. W formularzu należy użyć redirect: false, aby samodzielnie obsługiwać błędy, oraz zawsze stosować strategię JWT razem z danymi logowania.
Ucz się React dzięki korepetycjom AI — za darmo
Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.
- Kursy
- 88
- Lekcje
- 324
Często zadawane pytania
Czy lekcja „Dostawca Credentials i niestandardowe logowanie” jest bezpłatna?
Tak — pełny tekst „Dostawca Credentials i niestandardowe logowanie” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu React Academy, przejdź na CoddyKit PRO. Kurs React Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Dostawca Credentials i niestandardowe logowanie”?
Uwierzytelnianie użytkowników względem bazy danych za pomocą dostawcy credentials i niestandardowego formularza logowania. Ćwiczysz React Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć React Academy?
Nie wymagamy żadnego doświadczenia. React Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „Dostawca Credentials i niestandardowe logowanie”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji React Academy?
Tak. Każda lekcja React Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Konfiguracja Auth.js w Next.js App Router
- Zarządzanie sesją i hook useSession
- Dostawca Credentials i niestandardowe logowanie
- Ochrona tras oparta na middleware