How to handle server side logins?
Answered
Minskin posted this in #help-forum
MinskinOP
Hey guys im kind of new to nextjs, and want to recreate an old project i did with vuejs in nextjs to learn it.
My current goal is to recreate the login functionality, with vuejs this was simple, because everything was shipped to the client anyways. Now with nextjs im a bit confused, because to catch the form submit i need to use a client side component, but do i also send the request from the client direclty to my backend (Ktor), or do i loop it through the nextjs server first, to save the cookies and stuff on the nextjs serve. And if so, how can i do that?
My current goal is to recreate the login functionality, with vuejs this was simple, because everything was shipped to the client anyways. Now with nextjs im a bit confused, because to catch the form submit i need to use a client side component, but do i also send the request from the client direclty to my backend (Ktor), or do i loop it through the nextjs server first, to save the cookies and stuff on the nextjs serve. And if so, how can i do that?
Answered by nehalist
seems like you've mixed up the route handler with the lib config; route handlers need to be exported as
GET
and POST
. see https://nehalist.io/authentication-for-nextjs-with-nextauth-part-1/#basic-configuration at route handler section.46 Replies
MinskinOP
Is it still ok to use axios for reaching out to my backend which handles my auth?
MinskinOP
Maybe im on the wrong here but i what i wanto to achieve is kind of:
Frontend (handeled by my nextjs server)
Next js server -> Kotlin Backend
Frontend (handeled by my nextjs server)
Next js server -> Kotlin Backend
there's a lot to unpack here. the easiest approach to adding auth to your next app is nextauth. I've recently published a beginner-friendly post on how to add it on my blog, https://nehalist.io/authentication-for-nextjs-with-nextauth-part-1/
if you still want to handle everything by yourself (which I'd highly advise against, since auth is a very complex topic), you can take a look at https://tanstack.com/query/v4/docs/framework/react/reference/useQuery which will handle requests for you in a very convinient way. you're still going to need axios, but useQuery will make things significantly easier.
if you still want to handle everything by yourself (which I'd highly advise against, since auth is a very complex topic), you can take a look at https://tanstack.com/query/v4/docs/framework/react/reference/useQuery which will handle requests for you in a very convinient way. you're still going to need axios, but useQuery will make things significantly easier.
one possible approach would be to submit your form to a server action (https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations), do your login logic there and return a proper response (like cookies etc). but again, I would not do that at all
MinskinOP
Yes, but this looks like my auth would directly be sitting in my nextJS application, and i have a separate backend which already handels all of my logic.
what do you mean by handles all your logic?
MinskinOP
User database, sending emails etc. protecting routes ...
you can add custom providers to next auth: https://next-auth.js.org/v3/configuration/providers#adding-a-new-provider
MinskinOP
this looks good 👍
glad to hear that 🙂
MinskinOP
In the docs it is using the pages router: pages/api/auth/[...nextauth].js
How would this change when i use the app directory?
src/app/api/auth/[...nextauth]/route.ts
(or without the src
dir if you don't use that); the entire setup process is on my blog in caseMinskinOP
thanks for the help :)
glad I could help! 🙂
MinskinOP
From what i see, when i want to use the useSession function, i need to wrap my pages inside a SessionProvider, but this makes them a client component?
Is there another way to do this_
I've mentioned this in my post; wrapping components within client components doesn't hurt your seo. or what other issue do you have with client components?
MinskinOP
No this was just a general question
MinskinOP
i have the feeling that my config is not really doing what it should do
This is my current layout
import CredentialsProvider from "next-auth/providers/credentials";
import { baseURL } from "@/app/api/api";
import { NextAuthOptions } from "next-auth";
import NextAuth from "next-auth"
export const authOptions: NextAuthOptions = ({
providers: [
CredentialsProvider({
name: 'Credentials',
// The credentials is used to generate a suitable form on the sign in page.
// You can specify whatever fields you are expecting to be submitted.
// e.g. domain, username, password, 2FA token, etc.
credentials: {
email: { label: "Email", type: "text", placeholder: "jsmith" },
password: { label: "Password", type: "password" }
},
async authorize(credentials, req) {
const {email, password} = credentials as any
const res = await fetch(`${baseURL}/auth/login`, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(email, password)
})
const user = (await res.json()).user;
if (res.ok && user)
return user
return null
}
})
],
session: {
strategy: "jwt"
},
pages: {
signIn: "/auth/login"
}
})
export default NextAuth(authOptions);
And this is my config
but when i use the signIn() method to get redirect to the login page, the issue i get is /api/auth/error
anything in the console regarding the error?
MinskinOP
i only get a 404 because that page doesnt exist
Problem is, i get redirected instantly, so the console gets cleared afterwards
i mean your terminal, not browser console
MinskinOP
looks fine aswell
additionally, you can set "preserve log" in browser consoles to keep the log
MinskinOP
your signIn page says "/auth/login", but you put your next route handler under "/api/auth/login"
doesn't seem right
MinskinOP
its 2 different folders
├── api
│ ├── api.ts
│ └── auth
│ └── [...nextauth].ts
├── auth
│ ├── login
│ │ └── page.tsx
│ └── register
│ └── page.tsx
├── favicon.ico
├── globals.css
├── layout.tsx
├── page.tsx
└── providers.tsx
│ ├── api.ts
│ └── auth
│ └── [...nextauth].ts
├── auth
│ ├── login
│ │ └── page.tsx
│ └── register
│ └── page.tsx
├── favicon.ico
├── globals.css
├── layout.tsx
├── page.tsx
└── providers.tsx
i can also access the page by going to /auth/login
what do you see when you open /api/auth/signin (AND commenting out the
pages
section in your config)?MinskinOP
404
just to be sure: your api directory is within the
app
directory?MinskinOP
yes
app/api/auth/[...nextauth].ts
seems like you've mixed up the route handler with the lib config; route handlers need to be exported as
GET
and POST
. see https://nehalist.io/authentication-for-nextjs-with-nextauth-part-1/#basic-configuration at route handler section.Answer
MinskinOP
ah i see
Yes redirect is working now
thanks