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)
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: '[email protected]' }
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 */ },
}
You can use callbacks
here. https://next-auth.js.org/configuration/callbacks
callbacks: {
async signIn(user, account, profile) {
return true
},
async redirect(url, baseUrl) {
return baseUrl
},
async session(session, user) {
return session
},
async jwt(token, user, account, profile, isNewUser) {
return token
}
}
in signIn
callback, you can get accessToken and tokenId
from provider login. Here, call your DRF API and pass those tokens to your DRF and when you get back the access_token
and refresh_token
from DRF. Add them to your user instance. And then in JWT
callback, get the access
and refresh
from user
and add them into token
Got this from some blog
Though, you also need to handle the refresh token.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With