Не удается получить доступ к авторам (NextAuth 5) на стороне сервера токенов доступа в Next.js 15 с серверной частью Django
Я пытаюсь настроить аутентификацию в моем Next.js приложении, используя NextAuth.js серверную часть Django. В качестве поставщика Oauth я использую django-oauth-toolkit.
Цель состоит в том, чтобы передавать токен доступа в заголовке авторизации при выполнении запросов к API Django.
Я успешно настроил провайдера OAuth2 в Auth.js и могу войти в систему через систему аутентификации Django.
Однако, когда я пытаюсь получить токен доступа на стороне сервера в моем Next.js приложении (в серверном компоненте), я не могу его найти.
Я стараюсь следовать официальному руководству по бэкендам третьих частей: https://github.com/nextauthjs/next-auth-example
Я использую Extjs 15.1.7 и Authjs (NextAuth.js версия 5)
Вот соответствующий код:
src\auth.ts
import NextAuth from "next-auth"
import "next-auth/jwt"
declare module "next-auth" {
interface Session {
accessToken?: string
}
}
declare module "next-auth/jwt" {
interface JWT {
accessToken?: string
}
}
const DJANGO_URL = process.env.NEXT_PUBLIC_DJANGO_URL;
const NEXTJS_URL = process.env.NEXT_PUBLIC_NEXTJS_URL;
export const { handlers, auth, signIn, signOut } = NextAuth({
providers: [{
id: "django", // signIn("my-provider") and will be part of the callback URL
name: "Django", // optional, used on the default login page as the button text.
type: "oauth", // or "oauth" for OAuth 2 providers
userinfo: `${DJANGO_URL}/api/o/userinfo/`,
token: `${DJANGO_URL}/api/o/token/`,
wellKnown: `${DJANGO_URL}/api/o/.well-known/openid-configuration/`,
authorization: {
params: {
prompt: "login",
scope: "openid read write",
redirect_uri: `${NEXTJS_URL}/api/auth/callback/django`,
},
},
issuer: `${DJANGO_URL}/api/o`, // to infer the .well-known/openid-configuration URL
clientId: process.env.DJANGO_ID,
clientSecret: process.env.DJANGO_SECRET,
async profile(profile) {
return{
id: profile.sub,
email: profile.email,
}
},
}],
pages:{
signIn: "/login",
},
session: { strategy: "jwt" },
callbacks: {
authorized: async ({ auth }) => {
// Logged in users are authenticated, otherwise redirect to login page
return !!auth
},
jwt({ token, trigger, session, account }) {
if (trigger === "update") token.name = session.user.name
if (account?.provider === "django") {
return { ...token,
accessToken: account.access_token
}
}
return token
},
async session({ session, token }) {
if (token?.accessToken) session.accessToken = token.accessToken
return session
},
},
})
и затем я настроил прокси-сервер в качестве руководства, чтобы каждый запрос, начинающийся с "/api/", перенаправлялся на серверную часть с токеном доступа в заголовках, таким образом:
src\app\api\ [...proxy]\route.ts
import { auth } from "@/auth"
import { NextRequest, NextResponse } from "next/server"
async function handler(request: NextRequest) {
console.log("📢 Route Handler activated!")
const session = await auth()
console.log("🧐 Session:", session)
if (!session?.accessToken) {
console.log("⛔ No token in session.");
return NextResponse.json("Error Unauthorized 401")
}
const headers = new Headers(request.headers)
headers.set("Authorization", `Bearer ${session?.accessToken}`)
headers.set("Accept", "application/json")
let backendUrl = "https://localhost:8000/"
let url = request.nextUrl.href.replace(request.nextUrl.origin, backendUrl)
let result = await fetch(url, {
headers, body:
request.body,
credentials: "include"
})
let data = await result.json();
return NextResponse.json(data)
}
export const dynamic = "force-dynamic"
export { handler as GET, handler as POST }
а затем серверный компонент, максимально простой:
src\компоненты\usermenu.tsx
async function getUserData() {
const res = await fetch("https://localhost:3000/api/users/customuser/me/"); //request handled by the [...proxy]
if (!res.ok) {
throw new Error("Error retrieving user data");
}
return res.json();
}
export default async function UserProfilePage() {
const userData = await getUserData();
return (
<div>
{JSON.stringify(userData, null, 2)}
</div>
);
}
Однако, когда запрос обрабатывается на стороне сервера (в обработчике маршрута API или серверном компоненте), токен недоступен. Я пытался зарегистрировать токен и проверить файлы cookie, но, похоже, ничего не работает.
Я использую HTTPS локально как для своих приложений Next.js, так и для приложений Django, и я создал свои SSL-сертификаты вручную.
У меня есть следующие вопросы:
- Как я могу корректно получить следующий токен аутентификационного доступа на стороне сервера в моем приложении Next.js?
- Есть ли какой-то особый способ настроить мой сеанс или файлы cookie, чтобы убедиться, что токен доступен на стороне сервера?
- Может ли проблема быть связана с SSL-сертификатами, которые я использую локально, и как я могу это решить, если да?
- Что-то не так с тем, как я использую auth() или получаю доступ к сеансу в моем приложении Next.js?
Большое вам спасибо за уделенное время и помощь. Я искренне ценю ваш опыт и содействие в решении этой проблемы! Я не могу выразить словами, как я благодарен вам за вашу поддержку. Ваши идеи были бесценны, и я благодарен вам за то, что вы помогли мне пройти через это!