wise-white
wise-white2y ago

Auth0 Login on Next.js

Has anyone else tried to set Auth0 in the Refine Next.js version? I'm having trouble to accomplish the same effect, as the refine doc is based on React https://refine.dev/docs/advanced-tutorials/auth/auth0/. I tried to adapt following the Auth0 doc https://auth0.com/docs/quickstart/webapp/nextjs/01-login. The odd thing is it also have to move the authProvider inside the App component to access a hook through:
const App = () => {
const { isLoading, isAuthenticated, user, logout, getIdTokenClaims } =
useAuth0(); // <- this one

if (isLoading) {
return <span>loading...</span>;
}

const authProvider: AuthProvider = {
login: () => {
...
const App = () => {
const { isLoading, isAuthenticated, user, logout, getIdTokenClaims } =
useAuth0(); // <- this one

if (isLoading) {
return <span>loading...</span>;
}

const authProvider: AuthProvider = {
login: () => {
...
The Next.js version uses another hook called useUser, but still, I have a dependency of the authProvider in the [[...refine]].tsx file. I'd appreciate anyone's help, thanks.
24 Replies
fascinating-indigo
fascinating-indigo2y ago
Can you reproduce the issue ? Stackblitz or GitHub repo will be awesome. We will look into it as a first thing tomorrow
wise-white
wise-whiteOP2y ago
https://github.com/Daniel-Boll/auth0-login-next I have not provided the Auth0 secrets, if you guys happen to need it contact me. Also I have not changed the authProvider because the experiments I was doing might be so wrong that will only confuse you guys. I left some @here markers to the important places
fascinating-indigo
fascinating-indigo2y ago
thank you so much 🙏 @danielboll, you need to move authProvider inside <App> because useAuth() cannot work outside react component. i'm trying to create nextjs example with auth0. but auth0 sdk have issues with nextjs 13 at the moment. im looking for workaround to work with refine data-provider. i will inform you when i found work around https://github.com/auth0/nextjs-auth0/issues/889
wise-white
wise-whiteOP2y ago
Yeah, but the [[...refine]].tsx also needs the authProvider, that's where I got stuck on. Okay, thank you for you effort, if you need anything else I'm happy to help
fascinating-indigo
fascinating-indigo2y ago
We are investigating the issue. We will inform you as soon as possible
wise-white
wise-whiteOP2y ago
✔ Choose a project template · refine-react ✔ Choose your backend service to connect: · data-provider-custom-json-rest ✔ Do you want to use a UI Framework?: · mui ✔ Do you want to customize the Material UI theme?: · mui-extend-theme ✔ Do you want to customize the Material UI layout?: · mui-custom-layout ✔ Do you want to add dark mode support?: · mui-dark-mode ✔ Do you need any Authentication logic?: · auth-provider-auth0 ✔ Do you need i18n (Internationalization) support?: · i18n-mui ✔ Do you want to add example pages?: · mui-example-pages ✔ Do you want to add kbar command interface support?: · kbar ✔ Choose a package manager: · pnpm ✔ Would you mind sending us your choices so that we can improve superplate? · yes I also tried with the React version using the CLI as shown, as it is just inserting my credentials in the AuthProvider also doesn't work, I login, but cannot access /posts for example, still stuck to the /login altough logged
fascinating-indigo
fascinating-indigo2y ago
Hi @danielboll, i created PR for you https://github.com/Daniel-Boll/auth0-login-next/pull/1 but there are some bad practice this is sending request on every route change. to solve this, maybe you should only check hasCookie ? Promise.resolve() : Promise.reject() and your backend should validate auth0 token and return 401 or 403. after that u can implement ideal logic on authPRovider.checkError
checkAuth: async (params) => {
const cookies = nookies.get(params)

try {
const res = await axios.get(`http://localhost:3000/api/auth/me`, {
headers: {
cookie: `appSession=${cookies['appSession']}`,
},
})
return res.status === 200 ? Promise.resolve() : Promise.reject()
} catch (error) {
return Promise.reject()
}
}
checkAuth: async (params) => {
const cookies = nookies.get(params)

try {
const res = await axios.get(`http://localhost:3000/api/auth/me`, {
headers: {
cookie: `appSession=${cookies['appSession']}`,
},
})
return res.status === 200 ? Promise.resolve() : Promise.reject()
} catch (error) {
return Promise.reject()
}
}
After auth sdk release nextjs13 fix. we will write documentation for full example. also we have https://next-auth.js.org/ implementation in our backlog.
wise-white
wise-whiteOP2y ago
Thank you @alicanerdurmaz, I will try it ASAP. NextAuth will eventually be a great addition to Refine, which is already awesome 😃 About this problem on Auth0 and React, should I create another topic?
fascinating-indigo
fascinating-indigo2y ago
of course. thank you for helping us ! 🙏
wise-white
wise-whiteOP2y ago
And thank you for helping me!
fascinating-indigo
fascinating-indigo2y ago
i run this example on my machine https://refine.dev/docs/advanced-tutorials/auth/auth0/ it's works as expected. what is your error output ? did you change Auth0Provider props ? src/index.ts
<React.StrictMode>
<Auth0Provider
domain='dev-0s583yip.us.auth0.com'
clientId='nB61Zm0BP0YqyrbiHdMxtrMHyAPmEZFU'
redirectUri={window.location.origin}>
<App />
</Auth0Provider>
</React.StrictMode>
<React.StrictMode>
<Auth0Provider
domain='dev-0s583yip.us.auth0.com'
clientId='nB61Zm0BP0YqyrbiHdMxtrMHyAPmEZFU'
redirectUri={window.location.origin}>
<App />
</Auth0Provider>
</React.StrictMode>
wise-white
wise-whiteOP2y ago
Yeah, running this one works fine, but if I create a new refine-CRA app with the auth0 as a AuthProvider it doesn't
fascinating-indigo
fascinating-indigo2y ago
ohh sorry. i will check with this options
wise-white
wise-whiteOP2y ago
Yep, the Auth0-party works fine I even indeed log-in, but I think there's a problem with the authProvider it do not detect that I have the authentication I tried tying the authProvider with a dependency array of something from the useAuth0 through useMemo, without success tho
fascinating-indigo
fascinating-indigo2y ago
useMemo not necessary. in the example, checkAuth looks for token. if token exist, it assumes you are authenticated.
checkAuth: async () => {
try {
const token = await getIdTokenClaims()
if (token) {
axios.defaults.headers.common = {
Authorization: `Bearer ${token.__raw}`,
}
return Promise.resolve()
} else {
return Promise.reject()
}
} catch (error) {
return Promise.reject()
}
},
checkAuth: async () => {
try {
const token = await getIdTokenClaims()
if (token) {
axios.defaults.headers.common = {
Authorization: `Bearer ${token.__raw}`,
}
return Promise.resolve()
} else {
return Promise.reject()
}
} catch (error) {
return Promise.reject()
}
},
backend should determine do you have auth or not and should return 403 or 401 . after that for example, if 403 you should refresh tokens, if 401 you should logout.
checkError: () => Promise.resolve(),
checkError: () => Promise.resolve(),
How is the scenario where authProvider doesn't work properly? i delete tokens from chrome. i redirected to login page
wise-white
wise-whiteOP2y ago
But when you logged in you get to the /posts page for instance?
fascinating-indigo
fascinating-indigo2y ago
yes i did
wise-white
wise-whiteOP2y ago
Wow 😵‍💫 I don't I'll try creating the project again
fascinating-indigo
fascinating-indigo2y ago
i tried https://refine.dev/docs/advanced-tutorials/auth/auth0/ this i didn't check npm create refine-app yet. i use example repo now i will try to debug this
wise-white
wise-whiteOP2y ago
Oh, right, my problem was exactly in this scenario, using the advanced tutorial worked for me as well
fascinating-indigo
fascinating-indigo2y ago
okay i will check and return you asap🙏 @danielboll hi again, can you add this to App.tsx
if (isLoading) {
return <span>loading...</span>;
}
if (isLoading) {
return <span>loading...</span>;
}
you can add here
function App() {
const { isLoading, user, logout, getIdTokenClaims } = useAuth0()
const { t, i18n } = useTranslation()

if (isLoading) {
return <span>loading...</span>
}

const authProvider: AuthProvider = {

---
---
function App() {
const { isLoading, user, logout, getIdTokenClaims } = useAuth0()
const { t, i18n } = useTranslation()

if (isLoading) {
return <span>loading...</span>
}

const authProvider: AuthProvider = {

---
---
this problem occurs becase useAuth0 try to login, but still in loading state. that means getIdTokenClaims() returns undefined and we are redirecting to login page we will fix npm create refine app template. thank you 🙏
wise-white
wise-whiteOP2y ago
Niiiice, now it works You were very kind and helpful, thank you so much 🙏
fascinating-indigo
fascinating-indigo2y ago
im glad to hear that 🙏 thank you for your clear explanation the issues
Omer
Omer2y ago
Hey @danielboll , Hope you're doing well. We released our NextAuth.js example today. If you're still interested, you can take a look at it here: https://refine.dev/docs/examples/next-js/NextAuth.js/.
Authentication with NextAuth.js | refine
refine allows you to build your SSR supported web applications using Next.js. With this example, you can see how to make a simple refine app in Next.js and NextAuth.js with Authentication features.