Search code examples
javascriptreactjsaxiosredux-toolkitrtk-query

How do i get headers using redux toolkit query


In a react app, i'm using RTKQ to access my endpoints(django), in a login endpoint, it returns access and refresh token which im saving in an auth slice. The problem is, I also want to get an x-csrftoken from the headers because I need that token to send to the backend when hitting refresh endpoint. When using axios, I'm getting the headers from the backend, but when using RTK Query, the headers in the meta are empty. headers available when using axios

headers empty when using rtkq

Here is how i'm accessing the endpoints, specifically the login endpoint

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import { setCredentials, setCSRFToken, logOut } from '../../features/auth/authSlice'


const baseQuery = fetchBaseQuery({
    baseUrl: 'http://127.0.0.1:8000/api',
    credentials: 'include',
    prepareHeaders: (headers, { getState }) => {
        const token = getState().auth.token

        if (token) {
            headers.set("Authorization", `Bearer ${token}`)
        }

        return headers
    },
})

const baseQueryWithReauth = async (args, api, extraOptions) => {

    const result = await baseQuery(args, api, extraOptions);
    const xcsrftoken = result.meta.response.headers['x-csrftoken'];
    if (xcsrftoken) {
        api.dispatch(setCSRFToken(xcsrftoken));
    }

    return result
}



export const apiSlice = createApi({
    baseQuery: baseQueryWithReauth,
    endpoints: builder => ({})
})

when i log the result, i only get the data(access and refresh tokens) but no headers.

then I access the login endpoint.

import { apiSlice } from "../../app/api/apiSlice";

export const authApiSlice = apiSlice.injectEndpoints({
    endpoints: builder => ({
        login: builder.mutation({
            query: credentials => ({
                url: '/auth/login',
                method: 'POST',
                body: credentials,
                headers: {
                    "Content-Type": "application/json"
                },
            }),
        }),
    })
})




export const {
    useLoginMutation
} = authApiSlice;

i'm very new to RTKQ, anyone with a solution?


Solution

  • Yea, so after going through web pages without any success, i finally figured that I needed to use transformresponse inside the login mutation, this basically means i had access to all results that came from the api, both the data and the meta, I could now extract the data in the meta in this case the x-csrftoken then return it so that when i called the mutation in the login form and passing it login credential, i also got back a token which was basically the one i needed.

    export const authApiSlice = apiSlice.injectEndpoints({
        endpoints: builder => ({
            login: builder.mutation({
                query: credentials => ({
                    url: '/auth/login',
                    method: 'POST',
                    body: credentials,
                    headers: {
                        "Content-Type": "application/json"
                    },
                }),
                transformResponse: async (response, meta) => {
                    // Extract the value of the "X-CSRF-Token" header from the response
                    const token = meta.response.headers.get('x-csrftoken')
                    
                    const data = await response;
                    // Return an object containing the parsed response data and the token value
                    return { data, token };
                   
    
                }
            }),
        })
    })