如何将Axios拦截器与Next-Auth一起使用

56lgkhnf  于 2022-10-15  发布在  iOS
关注(0)|答案(2)|浏览(219)

我正在将我的CRA应用程序转换为Nextjs,并且遇到了Axios拦截器模式的一些问题。
它可以工作,但我被迫创建一个Axios示例并将其传递给每个API调用。
有没有更好的方法来做这件事?
以下是我现在掌握的情况:
Profile.js

import { useSession } from 'next-auth/react'

function Profile(props) {
    const { data: session } = useSession()
    const [user, setUser] = useState()
    useEffect(()=> {
      const proc= async ()=> {
        const user = await getUser(session?.user?.userId)
        setUser(user)
      }
      proc()
    },[])

    return <div> Hello {user.userName}<div>
}

getUser.js

export default async function getUser(userId) {
    const axiosInstance = useAxios()
    const url = apiBase + `/user/${userId}`
    const { data } = await axiosInstance.get(url)
    return data
}

useAxios.js

import axios from 'axios'
import { useSession } from 'next-auth/react'

const getInstance = (token) => {
    const axiosApiInstance = axios.create()

    axiosApiInstance.interceptors.request.use(
        (config) => {
            if (token && !config.url.includes('authenticate')) {
                config.headers.common = {
                    Authorization: `${token}`
                }
            }
            return config
        },
        (error) => {
            Promise.reject(error)
        }
    )

    return axiosApiInstance
}

export default function useAxios() {
    const session = useSession()
    const token = session?.data?.token?.accessToken
    return getInstance(token)
}
wwtsj6pe

wwtsj6pe1#

如果其他人有这个问题,我是这样解决它的(使用getSession):
获奖者:https://github.com/nextauthjs/next-auth/discussions/3550#discussioncomment-1993281

import axios from 'axios'
import { getSession } from 'next-auth/react'

const ApiClient = () => {
    const instance = axios.create()
    instance.interceptors.request.use(async (request) => {
        const session = await getSession()

        if (session) {
            request.headers.common = {
                Authorization: `${session.token.accessToken}`
            }
        }
        return request
    })

    instance.interceptors.response.use(
        (response) => {
            return response
        },
        (error) => {
            console.log(`error`, error)
        }
    )

    return instance
}

export default ApiClient()
6pp0gazn

6pp0gazn2#

受@Jar的启发,我的版本将首先检查现有的auth头,然后使用await getSession。这样,等待请求的次数就少了

axiosCilent.ts

const axiosCilent = () => {

    const axiosCilentVersion = Axios.create({
        baseURL: process.env.NEXT_PUBLIC_BACKEND_URL,
        headers: defaultHeaders,
        withCredentials: true,
    });

    /**
     * Special interceptors to add the auth header from session to each request
     */
    axiosCilentVersion.interceptors.request.use(async (request) => {

        // Are the auth headers already set? Do nothing if set already 
        const existingAuthHeader = hasAccessTokenHeader()

        // Auth headers not set, get token from session and set as default header
        if (!existingAuthHeader) {
            const session = await getSession()

            if (session && session.user) {
                // @ts-ignore Set access token as default setting
                setAccessToken(session.user.accessToken ?? '');
            }
        }

        return request
    })

    //#region Set or Check Defaults
    /**
     * Check if there's access token set
     * @returns
     */
    const hasAccessTokenHeader = (): boolean => {
        return axiosCilentVersion.defaults.headers.common['Authorization'] !== undefined ? true : false
    }

    /**
     * Set default auth header, must be done in the axios cilent class, otherwise will not be perma set
     * @param token
     */
    const setAccessToken = (token: string) => {
        axiosCilentVersion.defaults.headers.common['Authorization'] = `Bearer ${token}`
    }
    //#endregion

    return { axiosCilentVersion }
}

相关问题