I have an exiting Django project that I am trying to move from templates to NextJs frontend. I came across Next-Auth-js which seems to be nice in Next Auth.
However, the doc seems to focus more with JS related Backend Auth. Following this example I have sent the NEXTAUTH_URL environment variable to my DRF Endpoint localhost:8002. While the frontend runs on localhost:3000. While my _app.js looks like this:
<Provider options={{site: process.env.NEXTAUTH_URL,}} session={pageProps.session} > <Component {...pageProps} /> </Provider>
Using the Nav.js for a test, I changed the signin/out href to point to my Django endpoints but it seems next-auth-js ignores this and places a session fetch to my frontend http://localhost:3000/api/auth/session
instead of the the http://localhost:8002/api/auth/session
.
I will appreciate any assistance on how I can correctly/securely implement this authentication using Django Rest Framework (DRF)
Advertisement
Answer
I think that is the way it should work, your nextjs site would be a kind of proxy/middleware to your django API client -> nextjs -> DRF
, you should let it handle the sessions and for any action you need to do in your API for any authentication step, put code to hit those endpoints in the callbacks or events configuration, I think this tutorial is more accurate for your use case
from the docs
pages/api/auth/[…nextauth].js
import Providers from `next-auth/providers` ... providers: [ Providers.Credentials({ // The name to display on the sign in form (e.g. 'Sign in with...') 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: { username: { label: "Username", type: "text", placeholder: "jsmith" }, password: { label: "Password", type: "password" } }, authorize: async (credentials) => { // Add logic here to look up the user from the credentials supplied const user = { id: 1, name: 'J Smith', email: 'jsmith@example.com' } if (user) { // call your DRF sign in endpoint here // Any object returned will be saved in `user` property of the JWT return Promise.resolve(user) } else { // If you return null or false then the credentials will be rejected return Promise.resolve(null) // You can also Reject this callback with an Error or with a URL: // return Promise.reject(new Error('error message')) // Redirect to error page // return Promise.reject('/path/to/redirect') // Redirect to a URL } } }) ] ... events: { signOut: async (message) => { /* call your DRF sign out endpoint here */ }, }