[Solved] Issues with Middleware and Authentication in NextAuth.js with Drizzle and SQLite

Hi, I'm working with NextAuth (Auth.js) and Drizzle for the first time. I've successfully implemented OAuth for Google and GitHub, and I added the DrizzleAdapter and schema by following the NextAuth documentation. Now, I want to set up middleware to differentiate between protected and public routes based on whether the user is logged in. However, I'm running into a couple of issues: 1. The middleware check never seems to run. 2. !!auth?.user always returns false, even when the user is logged in. I've tried using the authorized method in the callbacks within NextAuthConfig. I’ve also watched a few YouTube videos, but for some reason, their approaches don't seem to work for me. I’m not sure what I might be doing wrong. Any guidance would be greatly helpfull! For context, I'm using SQLite with the better-sqlite3 library.
Next auth config file
middleware.ts file
14 Replies
Sameer
SameerOP2mo ago
Tried this, always getting this error.
No description
Sameer
SameerOP2mo ago
I have seperated the auth config and the main auth file.
auth.ts
import NextAuth from "next-auth";
import { cache } from "react";
import { authConfig } from "./config";

const { handlers, auth, signIn, signOut } = NextAuth(authConfig);
// const auth = cache(uncachedAuth);

export { auth, handlers, signIn, signOut };
auth.ts
import NextAuth from "next-auth";
import { cache } from "react";
import { authConfig } from "./config";

const { handlers, auth, signIn, signOut } = NextAuth(authConfig);
// const auth = cache(uncachedAuth);

export { auth, handlers, signIn, signOut };
auth-config.ts
import { db } from "@/drizzle";
import {
accounts,
sessions,
users,
verificationTokens,
} from "@/drizzle/db/schema";
import { DrizzleAdapter } from "@auth/drizzle-adapter";
import type { DefaultSession, NextAuthConfig } from "next-auth";
import GitHub from "next-auth/providers/github";
import Google from "next-auth/providers/google";

declare module "next-auth" {
interface Session extends DefaultSession {
user: {
id: string;
// ...other properties
// role: UserRole;
} & DefaultSession["user"];
}
}

export const authConfig = {
adapter: DrizzleAdapter(db, {
usersTable: users,
accountsTable: accounts,
sessionsTable: sessions,
verificationTokensTable: verificationTokens,
}),
providers: [Google, GitHub],
pages: {
signIn: "/login",
},
callbacks: {
authorized: async ({ auth }) => {
// Logged in users are authenticated, otherwise redirect to login page
return !!auth;
},
session: ({ session, user }) => ({
...session,
user: {
...session.user,
id: user.id,
},
}),
},
} satisfies NextAuthConfig;
auth-config.ts
import { db } from "@/drizzle";
import {
accounts,
sessions,
users,
verificationTokens,
} from "@/drizzle/db/schema";
import { DrizzleAdapter } from "@auth/drizzle-adapter";
import type { DefaultSession, NextAuthConfig } from "next-auth";
import GitHub from "next-auth/providers/github";
import Google from "next-auth/providers/google";

declare module "next-auth" {
interface Session extends DefaultSession {
user: {
id: string;
// ...other properties
// role: UserRole;
} & DefaultSession["user"];
}
}

export const authConfig = {
adapter: DrizzleAdapter(db, {
usersTable: users,
accountsTable: accounts,
sessionsTable: sessions,
verificationTokensTable: verificationTokens,
}),
providers: [Google, GitHub],
pages: {
signIn: "/login",
},
callbacks: {
authorized: async ({ auth }) => {
// Logged in users are authenticated, otherwise redirect to login page
return !!auth;
},
session: ({ session, user }) => ({
...session,
user: {
...session.user,
id: user.id,
},
}),
},
} satisfies NextAuthConfig;
Sameer
SameerOP2mo ago
Question: Is this because, I am using SQLite (better-sqlite3) driver, which seems to not be in edge compatible driver.
Drizzle ORM - Drizzle with Vercel Edge Functions
Drizzle ORM is a lightweight and performant TypeScript ORM with developer experience in mind.
TOSL
TOSL2mo ago
Need to see middleware.ts
Sameer
SameerOP2mo ago
Okay, I shifted from better-sqlite-3 to libSql from turso (which had edge compatible driver). Now that edge runtime error is resolved but no matter what how many times I login, it always redirect to /login route, and always return false for !!auth. middleware.ts
export { auth as middleware } from "@/utils/auth";

export const config = {
matcher: [
// Skip Next.js internals and all static files, unless found in search params
"/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)",
// Always run for API routes
"/(api|trpc)(.*)",
],
};
export { auth as middleware } from "@/utils/auth";

export const config = {
matcher: [
// Skip Next.js internals and all static files, unless found in search params
"/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)",
// Always run for API routes
"/(api|trpc)(.*)",
],
};
auth-config.ts
import { db } from "@/drizzle";
import {
accounts,
sessions,
users,
verificationTokens,
} from "@/drizzle/db/schema";
import { authApiPrefixRoute, protectedRoutes, publicRoutes } from "@/routes";
import { DrizzleAdapter } from "@auth/drizzle-adapter";
import type { DefaultSession, NextAuthConfig } from "next-auth";
import GitHub from "next-auth/providers/github";
import Google from "next-auth/providers/google";

declare module "next-auth" {
interface Session extends DefaultSession {
user: {
id: string;
// ...other properties
// role: UserRole;
} & DefaultSession["user"];
}
}

export const authConfig = {
adapter: DrizzleAdapter(db, {
usersTable: users,
accountsTable: accounts,
sessionsTable: sessions,
verificationTokensTable: verificationTokens,
}),
providers: [Google, GitHub],
callbacks: {
authorized: async ({ auth }) => {
console.log("authorized", !!auth);
return !!auth;
},
session: ({ session, user }) => ({
...session,
user: {
...session.user,
id: user.id,
},
}),
},
} satisfies NextAuthConfig;
import { db } from "@/drizzle";
import {
accounts,
sessions,
users,
verificationTokens,
} from "@/drizzle/db/schema";
import { authApiPrefixRoute, protectedRoutes, publicRoutes } from "@/routes";
import { DrizzleAdapter } from "@auth/drizzle-adapter";
import type { DefaultSession, NextAuthConfig } from "next-auth";
import GitHub from "next-auth/providers/github";
import Google from "next-auth/providers/google";

declare module "next-auth" {
interface Session extends DefaultSession {
user: {
id: string;
// ...other properties
// role: UserRole;
} & DefaultSession["user"];
}
}

export const authConfig = {
adapter: DrizzleAdapter(db, {
usersTable: users,
accountsTable: accounts,
sessionsTable: sessions,
verificationTokensTable: verificationTokens,
}),
providers: [Google, GitHub],
callbacks: {
authorized: async ({ auth }) => {
console.log("authorized", !!auth);
return !!auth;
},
session: ({ session, user }) => ({
...session,
user: {
...session.user,
id: user.id,
},
}),
},
} satisfies NextAuthConfig;
route.ts
import { handlers } from "@/utils/auth";
export const runtime = "edge";
export const { GET, POST } = handlers;
import { handlers } from "@/utils/auth";
export const runtime = "edge";
export const { GET, POST } = handlers;
removing runtime export don't seem to have any effect
TOSL
TOSL2mo ago
Is it just auth or is it auth.user?
Sameer
SameerOP2mo ago
just auth I think, its working now
TOSL
TOSL2mo ago
Cool. If not, I think I'd need a simple codesandbox recreation to help anymore.
Sameer
SameerOP2mo ago
Okay, it doesn't work. 🫠 For some reason, if we sign in for the first time, it works. However, if we sign out and then sign in with the same account, it doesn't do anything and returns false for !!auth?.user. Now, it doesn't work at all, not even the first time. Codesandbox link For some reason, installing dependencies in sandbox was failing continuesly. here's the list of dependencies: pnpm add @auth/drizzle-adapter @libsql/client drizzle-orm next-auth
TOSL
TOSL2mo ago
What service are you using for db url and auth token? I need to get my own env vars
Sameer
SameerOP2mo ago
Turso
Installation - Turso
Learn how to install the Turso CLI on Mac, Linux and Windows.
Sameer
SameerOP2mo ago
Although, after the last message, I went ahead and rewrote the entire schema and auth configuration from scratch. I dropped all the data from the database for a clean start, and now it's working exactly how I wanted it to. I'm not entirely sure, but I think it was a schema issue since I was using database-based sessions and not cookies. Nonetheless, thank you for helping! ❤️
TOSL
TOSL2mo ago
perfect no problem

Did you find this page helpful?