Here are my core dependencies and it's versions from my package.json
file:
"mobx": "^6.5.0", "mobx-react": "^7.3.0", "next": "12.1.6", "next-auth": "4.2.1", "react": "17.0.1",
I am using next-auth to handle authentication im my next.js app, specifically to get and store my api accessToken
. The thing is, next-auth needs the app to be wrapped inside a SessionProvider
. So that we can access session
object later via the useSession
hook from next-auth
, to get the accessToken to make authenticated requests to my API.
This is the hook i made to make use of session
's accessToken
to make authenticated requests:
import { setupAuthAPI } from '@/services/authAPI'
import { useSession } from 'next-auth/react'
import { useEffect } from 'react'
const useAuthAPI = () => {
const { data: session } = useSession()
useEffect(() => {
const requestIntercept = setupAuthAPI().interceptors.request.use(
config => {
if (!config.headers.Authorization) {
config.headers.Authorization = `Bearer ${session?.accessToken}`
}
return config
},
error => Promise.reject(error)
)
return () => {
setupAuthAPI().interceptors.request.eject(requestIntercept)
}
}, [session])
return setupAuthAPI
}
export default useAuthAPI
Consider also that setupAuthAPI
is simply an Axios Instance.
And here is my Mobx store:
import { observer } from 'mobx-react'
import { makeAutoObservable } from 'mobx'
.....
.....
import { toast } from 'react-toastify'
import useAuthAPI from '@/hooks/useAuthAPI'
......
......
class ResellerStore implements ResellerStoreInterface {
resellerOptions: ResellerOption[]
loading = false
constructor() {
makeAutoObservable(
this,
{},
{
autoBind: true
}
)
}
async loadAll() {
const setupAuthAPI = useAuthAPI()
this.loading = true
this.resellerOptions = []
setupAuthAPI()
.get('Reseller/all')
.then(response => {
const newResellerOptions = []
response.data.forEach(reseller => {
newResellerOptions.push({
label: reseller.companyName,
value: reseller.id
})
})
this.resellerOptions = newResellerOptions
this.loading = false
})
}
}
export { observer }
const resellerStore = new ResellerStore()
export { resellerStore }
But with this implementation, i am getting the error: Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
I need some help trying to figure out the correct flow to use my accessToken
that is managed by next-auth
and to use it to make authenticated requests inside my mobx store. Thank you in advance.
I tried the implementation already described in the question. What I'm expecting is to use next-auth
to handle authentication in my next.js
app, and also be able to use the accessToken
managed by it inside my mobx store to make authenticated requests.
What I did that solved my problem was to put my API interceptor in a HOC that wraps my app, one layer below my SessionProvider
. This way, my interceptor can access useSession
data, since it is now in a React Component
.