Provedor de credenciais e login personalizado
Autentique usuários em um banco de dados com um provedor de credenciais e um formulário de login personalizado.
Provedor de credenciais e login personalizado é uma aula grátis de React Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de React Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de React Academy inclui 4 aulas no total.
Quando usar o provedor de credenciais
Use o provedor de credenciais quando a autenticação for feita no seu próprio banco de dados (e-mail + senha), em vez de um provedor OAuth. Isso exige um tratamento cuidadoso do hash de senhas e da segurança.
Definindo o provedor de credenciais
Adicione Credentials à matriz de provedores. A função authorize recebe as credenciais enviadas e retorna um objeto de usuário ou 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 };
},
}),
],
});Formulário de login personalizado
Crie um formulário de login como um Componente de cliente que chame signIn('credentials', { email, password }) de 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 para tratamento de erros
Passe redirect: false para signIn() a fim de receber o objeto de resultado e tratar os erros no componente, em vez de redirecionar para uma página de erro.
const result = await signIn('credentials', { email, password, redirect: false });
if (result?.error) {
// result.error is 'CredentialsSignin' for auth failures
setError('Invalid email or password');
}Validação com Zod em authorize
Valide as credenciais com Zod dentro da função authorize antes de consultar o banco de dados.
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
}Estratégia de sessão para credenciais
O provedor de credenciais exige a estratégia de sessão JWT (não é necessário um adaptador de banco de dados para as sessões). Defina session: { strategy: 'jwt' } explicitamente.
export const { handlers, auth } = NextAuth({
session: { strategy: 'jwt' },
providers: [Credentials({ ... })],
});Adicionando campos personalizados à sessão
Transmita dados adicionais do usuário por meio das funções de retorno do JWT e da sessão para disponibilizá-los em 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;
},
},Hash de senhas
Sempre aplique hash às senhas com bcrypt antes de armazená-las. Nunca armazene senhas em texto simples.
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);Limitação de tentativas de login
Proteja o endpoint de credenciais contra ataques de força bruta limitando a taxa de tentativas de login com uma camada intermediária ou um armazenamento em memória.
// 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;Fluxo de registro
O registro é separado do Auth.js — crie o usuário no seu banco de dados (com a senha protegida por hash) por meio de uma Ação de servidor ou de uma rota de API e, depois, faça login com signIn('credentials', ...).
Verificação rápida
Por que você deve passar redirect: false ao chamar signIn() em um formulário de login personalizado?
Recapitulação
O provedor de credenciais chama sua função authorize com os dados enviados pelo formulário. Valide com Zod, compare as senhas protegidas por hash com bcrypt e retorne um objeto de usuário ou null. Use redirect: false no formulário para lidar com erros personalizados e sempre use a estratégia JWT com credenciais.
Perguntas Frequentes
A aula “Provedor de credenciais e login personalizado” é grátis?
Sim — o texto completo de “Provedor de credenciais e login personalizado” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de React Academy, atualize para CoddyKit PRO. O curso de React Academy inclui 4 aulas no total.
O que vou aprender em “Provedor de credenciais e login personalizado”?
Autentique usuários em um banco de dados com um provedor de credenciais e um formulário de login personalizado. Você pratica React Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar React Academy?
Nenhuma experiência prévia é necessária. React Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Provedor de credenciais e login personalizado”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de React Academy?
Sim. Cada aula de React Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Configurando Auth.js no App Router do Next.js
- Gerenciamento de sessões e hook useSession
- Provedor de credenciais e login personalizado
- Proteção de rotas baseada em middleware