deep-jade
deep-jade•9mo ago

Data Provider with API cookies

I hav an API that creates cookies which are used for authentication purpose (they contains jwt acces and refresh tokens). How can I tell my dataProvider to use that cookie whenever a request is sent to the API? The API and Refine backend are on two different sub-domains, I have cors allowing cross-domain origin and credentials set to true.
6 Replies
kapa.ai
kapa.ai•9mo ago
Hi @smilodon.x7. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To inform your data provider about the authentication credentials, you can send the authentication credentials with each request. After obtaining the authentication token, you can store it in cookies and send it with every request. In refine, you can use the dataProvider property of the <Refine> component to allow refine to communicate with the API. Here is an example of how to add a dataProvider to the refine component:
import { Refine } from "@refinedev/core";
import { authProvider, axiosInstance } from "./authProvider";
import { DataProvider } from "@refinedev/strapi-v4";

function App() {
return (
<Refine
dataProvider={DataProvider(API_URL + `/api`, axiosInstance)}
//...
/>
);
}

export default App;
import { Refine } from "@refinedev/core";
import { authProvider, axiosInstance } from "./authProvider";
import { DataProvider } from "@refinedev/strapi-v4";

function App() {
return (
<Refine
dataProvider={DataProvider(API_URL + `/api`, axiosInstance)}
//...
/>
);
}

export default App;
In the above code, axiosInstance is imported from the authProvider.ts file. This instance can be configured to include the authentication token in every request. Here is an example of how to create an authProvider:
import { AuthProvider } from "@pankod/refine-core";
import Cookies from "js-cookie";
import axios from "axios";
import { promises } from "dns";
const axiosInstance = axios.create();

export const TOKEN_KEY = "refine-auth";
export const authProvider: AuthProvider = {
login: async () => {
return Promise.resolve();
},
logout: () => {
localStorage.removeItem(TOKEN_KEY);
return Promise.resolve();
},
checkError: () => Promise.resolve(),
checkAuth: async () => {
let response = await axiosInstance.get("/api/auth")
if (!(response.status === 200)) {
const error = response.statusText;
return Promise.reject(error);
}
return Promise.resolve();
},
getPermissions: () => Promise.resolve(),
};
import { AuthProvider } from "@pankod/refine-core";
import Cookies from "js-cookie";
import axios from "axios";
import { promises } from "dns";
const axiosInstance = axios.create();

export const TOKEN_KEY = "refine-auth";
export const authProvider: AuthProvider = {
login: async () => {
return Promise.resolve();
},
logout: () => {
localStorage.removeItem(TOKEN_KEY);
return Promise.resolve();
},
checkError: () => Promise.resolve(),
checkAuth: async () => {
let response = await axiosInstance.get("/api/auth")
if (!(response.status === 200)) {
const error = response.statusText;
return Promise.reject(error);
}
return Promise.resolve();
},
getPermissions: () => Promise.resolve(),
};
In the above code, axiosInstance is used to send a GET request to "/api/auth". You can modify this code to include the authentication token in the headers of every request. For more information, you can refer to the refine's dataProvider prop component documentation (https://refine.dev/docs/api-reference/core/components/refine-config/#dataprovider) and the refine's guide on using authentication with data provider (https://refine.dev/docs/guides-concepts/authentication/#usage-with-data-provider-). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai•9mo ago
<@305970367405490186> kapa.ai is still learning and improving, please let us know how it did by reacting below
rival-black
rival-black•8mo ago
Hello @smilodon.x7 as bot mentioned, you can pass a client to your data provider which reads cookies or you can swizzle and modify to read cookies and add to headers: https://refine.dev/docs/tutorial/understanding-dataprovider/swizzle/#what-is-swizzle
deep-jade
deep-jade•8mo ago
Hello @batuhanw , thank you for your help 🙂 My API does not check the tokens within the headers but directly from the cookies created in the login route. Am I doing it the wrong way? Should I make my API check the header instead, then get the tokens from the cookies inside my authProvider and use them later with my dataProvider? I'm new to Refine and API development so please forgive me my beginner level 🙂
rival-black
rival-black•8mo ago
I think you can use withCredentials option to also send cookies: https://bobbyhadz.com/blog/javascript-axios-set-cookies
Set Cookies when making an Axios request in JS and Node | bobbyhadz
You can set the withCredentials property to true in the configuration object to set cookies when making an Axios HTTP request.
deep-jade
deep-jade•8mo ago
@batuhanw I swizzled the dataProvider and added the withCredentials in the axios.ts file like this : import { HttpError } from "@refinedev/core"; import axios from "axios"; const axiosInstance = axios.create({withCredentials: true}); axiosInstance.interceptors.response.use( (response) => { return response; }, (error) => { const customError: HttpError = { ...error, message: error.response?.data?.message, statusCode: error.response?.status, }; return Promise.reject(customError); } ); I tried with axios.defaults.withCredentials = true just in case but it did not work either