
После долгого поиска документации по этой проблеме, наконец, я решил написать этот пост, чтобы помочь разработчикам, оказавшимся в такой же ситуации.
Адаптер Mongodb — это утилита, которая предоставляет нам «метод» для сохранения пользователей/учетных записей/сеансов в Mongodb с использованием таких поставщиков, как Google, Github и т. д. Но что произойдет, если вы захотите сохранить свои пользовательские данные в mongodb?
Сначала я использовал пакет mongoose для управления им, но nextauth дает нам реализацию, которая ускоряет процесс, не прибегая к другим внешним библиотекам, таким как mongoose. Нам просто нужно использовать MongoClient и написать небольшую утилиту, чтобы поддерживать связь.
Настройте наш адаптер
npm install next-auth @next-auth/mongodb-adapter mongodb
Как говорится в документации, адаптер Mongodb не обрабатывает соединения автоматически, поэтому нам нужно передать клиентское подключение к адаптеру.
Адаптер MongoDB не обрабатывает соединения автоматически, поэтому вам нужно убедиться, что вы передаете адаптеру
MongoClient, который уже подключен. Ниже вы можете увидеть пример, как это сделать.
Клиент MongoDB
// This approach is taken from https://github.com/vercel/next.js/tree/canary/examples/with-mongodb
import { MongoClient } from "mongodb";
if (!process.env.MONGODB_URI) {
throw new Error('Invalid/Missing environment variable: "MONGODB_URI"');
}
const uri = process.env.MONGODB_URI;
const options = {};
let client;
let clientPromise: Promise<MongoClient>;
if (process.env.NODE_ENV === "development") {
// In development mode, use a global variable so that the value
// is preserved across module reloads caused by HMR (Hot Module Replacement).
if (!global._mongoClientPromise) {
client = new MongoClient(uri, options);
global._mongoClientPromise = client.connect();
}
clientPromise = global._mongoClientPromise;
} else {
// In production mode, it's best to not use a global variable.
client = new MongoClient(uri, options);
clientPromise = client.connect();
}
// Export a module-scoped MongoClient promise. By doing this in a
// separate module, the client can be shared across functions.
export default clientPromise;
Не забудьте создать переменную среды в файле .env с uri mongodb.
Учетные данные и обратные вызовы
Вы можете использовать методы, предоставляемые адаптером next-auth, чтобы найти своего пользователя, например, getUserByEmail (ваш «[email protected]»). И, конечно же, вы можете взять это письмо из учетных данных, getUserByEmail(credentials.username)
import clientPromise from "@/app/lib/mongodb";
import { MongoDBAdapter } from "@next-auth/mongodb-adapter";
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import GitHubProvider from "next-auth/providers/github";
export const authOptions = {
adapter: MongoDBAdapter(clientPromise),
providers: [
GitHubProvider({
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
}),
CredentialsProvider({
name: "credentials",
credentials: {
username: { label: "Username", type: "text", placeholder: "Aaron" },
password: { label: "Password", type: "password" },
},
async authorize(credentials, req) {
// Find your user in the database using MongoDBAdapter
const user = await authOptions.adapter.getUser(
"6471f710f772cf139bc5142e"
);
if (user) {
return user;
} else {
return null;
}
},
}),
],
secret: process.env.NEXTAUTH_SECRET,
session: {
// Set it as jwt instead of database
strategy: "jwt",
},
callbacks: {
async jwt({ token, user }) {
// Persist the OAuth access_token and or the user id to the token right after signin
if (user) {
token.accessToken = user.access_token;
token.id = user.id;
}
return token;
},
async session({ session, token }) {
// Send properties to the client, like an access_token and user id from a provider.
session.accessToken = token.accessToken;
session.user.id = token.id;
return session;
},
},
};
const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };
Обратите внимание: если вы хотите сохранить сеанс учетных данных, вам нужно установить session.strategy как «jwt». Поставщик учетных данных не сохраняет сеанс в базе данных.
Поставщик учетных данных можно использовать только в том случае, если для сеансов включены веб-токены JSON. Пользователи, прошедшие проверку подлинности с помощью поставщика учетных данных, не сохраняются в базе данных.
https://next-auth.js.org/configuration/providers/credentials
Даже вы можете сохранить пользовательские данные в сеансе пользователя. Просто передайте дополнительные параметры в обратный вызов сеанса.
Провайдер сеанса
Не забудьте обернуть layout.js компонентом SessionProvider, чтобы получить доступ пользователя ко всему приложению.
"use client";
import { SessionProvider } from "next-auth/react";
import "./globals.css";
export const metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({ children }) {
return (
<html lang="en">
<SessionProvider>
<body>{children}</body>
</SessionProvider>
</html>
);
}
Теперь вы можете получить доступ к URL-адресу https://localhost:3000/api/auth/signin/credentials и войти, используя свои учетные данные или через своего провайдера.
После этого у вас должен быть доступ к сессии и ее свойствам с помощью хука useSession.

А из бэкенда с помощью getServerSession.
import { authOptions } from "../auth/[...nextauth]/route";
import { getServerSession } from "next-auth";
export async function GET(Request) {
const session = await getServerSession(authOptions);
if (session) {
return new Response(JSON.stringify(session), { status: 200 });
} else {
return new Response("Not authenticated user!", { status: 401 });
}
}

Ссылки
Github: https://github.com/aaronaira/next-auth-example-mongodbadapter
Linkedin: https://www.linkedin.com/in/aaron-aira/