I want to secure my api routes
Unanswered
Iridescent shark posted this in #help-forum
Iridescent sharkOP
I want to secure my api routes with next-auth middleware, but if user is not authorized it redirect me to /sign-in page, but for api routes I want it to return 401 unauthorized response. How can I do it? I tried code below, but it didn't work
export default function middleware(req: NextRequest) {
if (req.nextUrl.pathname.startsWith('/api')) {
// do something here
} else {
return withAuth(function (request: NextRequestWithAuth) {
//do something here
})
}
}26 Replies
export { default } from "next-auth/middleware"middleware.ts???
Iridescent sharkOP
Default middleware redirect both api and page routes to /sign-in page, I want api routes just be respond with NextResponse.json({},{status:401}) unauthorized
show us your [...nextauth].ts file
Iridescent sharkOP
options.ts
import GithubProvider from 'next-auth/providers/github';
import GoogleProvider from 'next-auth/providers/google'
import { MongoDBAdapter } from "@next-auth/mongodb-adapter"
import clientPromise from '@/lib/mongodb-adapter';
import { NextAuthOptions } from 'next-auth';
const THIRTY_DAYS = 30 * 24 * 60 * 60
const THIRTY_MINUTES = 30 * 60
const authOptions: NextAuthOptions = {
session: {
strategy: 'jwt',
maxAge: THIRTY_DAYS,
updateAge: THIRTY_MINUTES
},
providers: [
GithubProvider({
clientId: process.env.GITHUB_ID as string,
clientSecret: process.env.GITHUB_SECRET as string
}),
GoogleProvider({
clientId: process.env.GOOGLE_ID as string,
clientSecret: process.env.GOOGLE_SECRET as string
}),
// EmailProvider({
// server: {
// host: process.env.EMAIL_SERVER_HOST,
// port: process.env.EMAIL_SERVER_PORT,
// auth: {
// user: process.env.EMAIL_SERVER_USER,
// pass: process.env.EMAIL_SERVER_PASSWORD
// }
// },
// from: process.env.EMAIL_FROM
// })
],
adapter: MongoDBAdapter(clientPromise),
pages: {
signIn: '/sign-in',
verifyRequest: '/verify-request'
},
callbacks: {
async jwt({ token, user }) {
if (user) {
token.uid = user.id
}
return token;
},
// If you want to use the role in client components
async session({ session, token }) {
if (session?.user) {
session.user.id = token.uid;
}
return session
},
}
}
export default authOptions;route.ts
import NextAuth from 'next-auth';
import authOptions from './options';
const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };Iridescent sharkOP
For example
If I'm not authorized and I send post request to
/api/posts/create -> response with status code 401 not authorized and maybe json message
If I'm not authorized and I go to
/posts/create -> I'm redirected to /sign-inthen add matcher in middleware
export { default } from "next-auth/middleware"
export const config = { matcher: ["/posts","/update-posts",...] }Iridescent sharkOP
Yes, but both routes /api/posts/create (backend, return json) and /posts/create fronend will be navigated to /sign-in page, but I want at /api/posts/create response with NextResponse.json()
wait a minute, could you please put some more light on the point "want to secure api routes??". These are already secured and can't be accessed by client side
So what's the issue with that
Iridescent sharkOP
Next Auths middleware works that if you don't provide auth token or session, it redirects you from page you want to access to /sign-in. For pages it is ok. But I also use it with my api routes which return json data. And if I'm not authorized they should return status code 401. Instead it return html page
Carpenter wasp
I had the same question what do you mean secure?. Maybe use TRPC or Zod for protected routes
Iridescent sharkOP
I mean if you don't send token or session with your for example get request, the endpoint should return status code 401 unauthorized instead of html page
Like a normal backend endpoint should do
Iridescent sharkOP
For example if I deploy my website to vercel, ok I secured pages and you can't navigate to /posts/create, but on the other hand any person can just send post request to /api/posts/create and create new post without authorization. But I want them to provide token or session data with post request, that's to secure api route
@Iridescent shark Click to see attachment
can I take a look at
/api/protected/route.tsIridescent sharkOP
it simple get route I use it to test
import { NextRequest, NextResponse } from "next/server";
export async function GET(req: NextRequest) {
return NextResponse.json({ message: "protected route" }, { status: 200 });
}you're using Mongodb correct??
Iridescent sharkOP
Yes, the only problem that api route renavigated to page instead of sending
401 unauthorized status codeThere is not problem with other part except next-auth middleware
you can do one thing then, use the id which is created by mongodb
for authentication perpose or else make a sandbox or something for us to look into it
with your description I'm only able to understand about 40-50% of it
Iridescent sharkOP
Thank you for the help, I need to search more about next-auth