最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

mongodb - The edge runtime does not support Node.js 'crypto' module error while adding mongoClient and trying to

programmeradmin1浏览0评论

My project uses Authjs for authentication, Ive followed the documentation in splitting the auth file into auth.config and pasted their middleware: /guides/edge-compatibility .

import NextAuth from "next-auth";
import authConfig from "@/app/auth.config";

export const { auth: middleware } = NextAuth(authConfig);

However I need to fetch the session on the middlware, which when I try to do, I get the error: Error: The edge runtime does not support Node.js 'crypto' module. Learn More:

here is my middlware:

import { NextResponse } from "next/server";
// import { jwtVerify } from "jose";

import { auth } from "@/app/api/auth";
import NextAuth from "next-auth";


export async function middleware(request) {
  // Error: The edge runtime does not support Node.js 'crypto' module.

  const session = await auth();
  console.log(session);

  return NextResponse.next();
}

// Middleware matcher configuration
export const config = {
  matcher: [
    "/dashboard/:path*",
    "/booking/:path*",
    "/",
    "/about",
    "/contact",
    "/admin/:path*",
    "/login/:path*",
    "/signup/:path*",
  ],
};

here is the authjs file:

import NextAuth from "next-auth";
import Google from "next-auth/providers/google";
import { MongoDBAdapter } from "@auth/mongodb-adapter";
import client from "./client";
import authConfig from "../auth.config";
const db = client.db(process.env.MONGODB_DB);

// Simple function to get user role from database
// async function getUserRole(email) {
//   const user = await db.collection("users").findOne({ email });
//   return user?.role || "user";
// }

export const { handlers, signIn, signOut, auth } = NextAuth({
  adapter: MongoDBAdapter(client),
  secret: process.env.NEXTAUTH_SECRET,
  session: {
    strategy: "jwt",
    maxAge: 30 * 24 * 60 * 60, // 30 days
  },
  ...authConfig,
  callbacks: {
    async jwt({ token, user, account }) {
      // Initial sign in
      if (account && user) {
        token.accessToken = account.access_token;
        token.refreshToken = account.refresh_token;
        token.accessTokenExpires = account.expires_at * 1000;
        token.userId = user.id;
        // token.role = user.role;
      }

      // Check if token needs refresh
      if (token.accessTokenExpires && Date.now() >= token.accessTokenExpires) {
        try {
          const response = await fetch(";, {
            headers: { "Content-Type": "application/x-www-form-urlencoded" },
            method: "POST",
            body: new URLSearchParams({
              client_id: process.env.AUTH_GOOGLE_ID,
              client_secret: process.env.AUTH_GOOGLE_SECRET,
              grant_type: "refresh_token",
              refresh_token: token.refreshToken,
            }),
          });

          const tokens = await response.json();

          if (!response.ok) throw tokens;

          return {
            ...token,
            accessToken: tokens.access_token,
            accessTokenExpires: Date.now() + tokens.expires_in * 1000,
            refreshToken: tokens.refresh_token ?? token.refreshToken,
          };
        } catch (error) {
          console.error("Error refreshing access token:", error);
          return { ...token, error: "RefreshAccessTokenError" };
        }
      }

      // Check for role updates on every request
      if (token.userId) {
        const currentUser = await db
          .collection("users")
          .findOne({ email: token.email });
        if (currentUser && currentUser.role !== token.role) {
          token.role = currentUser.role;
        }
      }

      return token;
    },

    async session({ session, token }) {
      if (token) {
        session.user.id = token.userId;
        session.user.role = token.role;
        session.accessToken = token.accessToken;
        session.error = token.error;
      }
      return session;
    },
  },
});

here is the auth.config file:

import Google from "next-auth/providers/google";
// import client from "./api/client";

// const db = client.db(process.env.MONGODB_DB); // Define db
// export async function getUserRole(email) {
//   const user = await db.collection("users").findOne({ email });
//   return user?.role || "user";
// }

export default {
  providers: [
    Google({
      clientId: process.env.AUTH_GOOGLE_ID,
      clientSecret: process.env.AUTH_GOOGLE_SECRET,
      authorization: {
        params: {
          prompt: "consent",
          access_type: "offline",
          response_type: "code",
          scope: "openid email profile",
        },
      },
      profile: async (profile) => {
        // Get role from database
        // const role = await getUserRole(profile.email);

        return {
          id: profile.sub,
          name: profile.name,
          email: profile.email,
          image: profile.picture,
          emailVerified: profile.email_verified ? new Date() : null,
          role: "admin",
        };
      },
    }),
  ],
};

here is the client file:

// This approach is taken from .js/tree/canary/examples/with-mongodb

import { MongoClient, ServerApiVersion } from "mongodb";

if (!process.env.MONGO_URI) {
  throw new Error('Invalid/Missing environment variable: "MONGO_URI"');
}

const uri = process.env.MONGO_URI;
const options = {
  serverApi: {
    version: ServerApiVersion.v1,
    strict: true,
    deprecationErrors: true,
  },
};

let client;

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._mongoClient) {
    global._mongoClient = new MongoClient(uri, options);
  }
  client = global._mongoClient;
} else {
  // In production mode, it's best to not use a global variable.
  client = new MongoClient(uri, options);
}

// Export a module-scoped MongoClient. By doing this in a
// separate module, the client can be shared across functions.
export default client;

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论