The right way to use conditional header in rtk query?
Asked Answered
U

1

5

I use rtk query and I want to pass header authentication for all of request except refresh token without header and this is my code is there a way to have condition or pass header to be empty? or can I have 2 fetchBaseQuery one for wieth header and other for refresh request?

 const baseQuery = fetchBaseQuery({
    baseUrl: 'https://xr1.bernetco.ir/api/v1/',
    prepareHeaders: (headers, { getState }) => {
        const user = (getState() as RootState).user.currentUser

        if (user) {
            headers.set('Authorization', `Bearer ${user.token.access}`)
        }
        return headers
    },
    credentials: 'include', // This allows server to set cookies
})

const baseQueryWithReauth: BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError> = async (
    args,
    api,
    extraOptions
) => {
    let result = await baseQuery(args, api, extraOptions)
    if (result.error && result.error.status === 401) {
        // try to get a new token

        const user = (api.getState() as RootState).user.currentUser
        const refreshResult = await baseQuery(
            { url: '/refresh-token/', method: 'POST', body: { refresh: user.token.refresh ?? '' } },
            api,
            extraOptions
        )
        
        
        const response = refreshResult.data as any
        if (response) {
            // store the new token
            api.dispatch(setCurrentUser(response.result))
            // retry the initial query
            result = await baseQuery(args, api, extraOptions)
        } else {
            api.dispatch(setCurrentUser(null))
        }
    }
    return result
}
Undressed answered 10/1, 2022 at 6:44 Comment(0)
N
17

prepareHeaders is also passed api.endpoint, so you can just make an exception there:

 const baseQuery = fetchBaseQuery({
    baseUrl: 'https://xr1.bernetco.ir/api/v1/',
    prepareHeaders: (headers, { getState, endpoint }) => {
        const user = (getState() as RootState).user.currentUser

        if (user && endpoint !== 'refresh') {
            headers.set('Authorization', `Bearer ${user.token.access}`)
        }
        return headers
    },
    credentials: 'include', // This allows server to set cookies
})

Of course, you will also have to call it like that then:

        const refreshResult = await baseQuery(
            { url: '/refresh-token/', method: 'POST', body: { refresh: user.token.refresh ?? '' } },
            { ...api, endpoint: 'refresh' },
            extraOptions
        )
Natalianatalie answered 10/1, 2022 at 8:32 Comment(1)
This type of setting header in the request does not work for the next page after login In fact, after setting the password in the cookie after the login page Because we don't have a token before login and, after login, the fateBaseQuery instance is sampled only once on the login page and doesn't have the token what is the solution?Filaria

© 2022 - 2024 — McMap. All rights reserved.