wise-white
wise-white10mo ago

Multiple Auth Provider in a single app. Possible?

Hi everyone! A refine newbie here. First, a huge thanks to refine team for building something pretty useful & keeping it open source. It's commendable. I had a question about refine entry point (https://refine.dev/docs/api-reference/core/components/refine-config/). Is it possible to have two different routes under two different refine entry points. The reason, I ask is because I would like to use different auth providers for one specific route while rest of the routes would have a different auth provider. Given that auth providers go hand in hand with refine entry point, I am wondering if it's possible to have two entry points. If not, let me know if it's possible to have two auth providers. One of the auth provider is a Custom Auth Provider and other is Azure Active Directory. Only one route is protected by AAD and rest all routes would be protected by Custom Auth Provider. TIA.
8 Replies
kapa.ai
kapa.ai10mo ago
Hi @pankaj_81531. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Hello and welcome to the refine community! We're glad to hear that you're finding refine useful. Regarding your question, refine does allow you to use multiple data providers in your app. However, the same functionality does not extend to auth providers. You can only pass one auth provider to the <Refine /> component. That being said, you could potentially create a custom auth provider that internally decides which auth method to use based on the route or some other parameter. This custom auth provider would essentially wrap your Custom Auth Provider and Azure Active Directory Auth Provider. Here's a simplified example of how you might structure this:
const customAuthProvider = {
// Your custom auth provider methods
};

const azureAuthProvider = {
// Your Azure AD auth provider methods
};

const authProvider = {
login: async (params) => {
if (params.route === 'azureRoute') {
return azureAuthProvider.login(params);
} else {
return customAuthProvider.login(params);
}
},
// Implement other methods in a similar way
};

<Refine authProvider={authProvider} />;
const customAuthProvider = {
// Your custom auth provider methods
};

const azureAuthProvider = {
// Your Azure AD auth provider methods
};

const authProvider = {
login: async (params) => {
if (params.route === 'azureRoute') {
return azureAuthProvider.login(params);
} else {
return customAuthProvider.login(params);
}
},
// Implement other methods in a similar way
};

<Refine authProvider={authProvider} />;
In this example, the login method of the authProvider checks the route and calls the corresponding method from either the customAuthProvider or the azureAuthProvider. You would need to implement the other methods (logout, check, etc.) in a similar way. Please note that this is a simplified example and you might need to adjust it based on your specific requirements and the APIs provided by your auth providers. For more information on auth providers in refine, you can refer to the authProvider documentation (https://refine.dev/docs/api-reference/core/providers/auth-provider/). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai10mo ago
<@1148728588506501242> kapa.ai is still learning and improving, please let us know how it did by reacting below
quickest-silver
quickest-silver10mo ago
Hello @pankaj_81531, currently multiple auth provider not possible but kapa.ai answers is great. is it works for you ?
wise-white
wise-white10mo ago
Hi @alicanerdurmaz - Thanks for checking. The answer looks good. We have not yet tried this but were able to design a solution. Once we implement, we would know better.
distinguished-silver
distinguished-silver2mo ago
Hi. I am also new here as well. once again, I say a big thanks to the refine team for this incredible work I also followed @kapa.ai 's response to setup a sort of 2 separate auth provider handler and it works great. Where I'm having an issue is with the useIsAuthenticated hook, and the Authenticated component not accepting props is there any workaround for this?
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- It's great to hear that you've managed to set up a dual auth provider handler! Regarding your issue with the useIsAuthenticated hook and the Authenticated component not accepting props, let's delve into some potential workarounds. Understanding useIsAuthenticated and <Authenticated /> The useIsAuthenticated hook and the <Authenticated /> component are designed to work with a single auth provider. They call the check method from the authProvider to determine the authentication status. Custom Hook for Dual Auth Providers To handle multiple auth providers, you can create a custom hook that internally decides which auth provider to use based on the route or some other parameter. Here's an example:
import { useQuery } from 'react-query';
import { useLocation } from 'react-router-dom';

const useCustomIsAuthenticated = () => {
const location = useLocation();
const isAzureRoute = location.pathname.startsWith('/azureRoute');

const checkAuth = async () => {
if (isAzureRoute) {
return azureAuthProvider.check();
} else {
return customAuthProvider.check();
}
};

return useQuery('isAuthenticated', checkAuth);
};
import { useQuery } from 'react-query';
import { useLocation } from 'react-router-dom';

const useCustomIsAuthenticated = () => {
const location = useLocation();
const isAzureRoute = location.pathname.startsWith('/azureRoute');

const checkAuth = async () => {
if (isAzureRoute) {
return azureAuthProvider.check();
} else {
return customAuthProvider.check();
}
};

return useQuery('isAuthenticated', checkAuth);
};
Custom <Authenticated /> Component You can also create a custom <Authenticated /> component that uses this custom hook:
import React from 'react';
import { useCustomIsAuthenticated } from './useCustomIsAuthenticated';
import { useGo } from '@refinedev/core';

const CustomAuthenticated = ({ children, fallback, loading }) => {
const { isLoading, data } = useCustomIsAuthenticated();
const go = useGo();

if (isLoading) {
return <>{loading}</> || null;
}

if (data.error) {
if (!fallback) {
go({ to: data.redirectTo || '/login', type: 'replace' });
return null;
}
return <>{fallback}</>;
}
if (data.authenticated) {
return <>{children}</>;
}

return null;
};

export default CustomAuthenticated;
import React from 'react';
import { useCustomIsAuthenticated } from './useCustomIsAuthenticated';
import { useGo } from '@refinedev/core';

const CustomAuthenticated = ({ children, fallback, loading }) => {
const { isLoading, data } = useCustomIsAuthenticated();
const go = useGo();

if (isLoading) {
return <>{loading}</> || null;
}

if (data.error) {
if (!fallback) {
go({ to: data.redirectTo || '/login', type: 'replace' });
return null;
}
return <>{fallback}</>;
}
if (data.authenticated) {
return <>{children}</>;
}

return null;
};

export default CustomAuthenticated;
Usage Now, you can use your custom <CustomAuthenticated /> component in your application:
import CustomAuthenticated from './CustomAuthenticated';

const MyPage = () => (
<CustomAuthenticated fallback={<div>Not Authenticated</div>} loading={<div>Loading...</div>}>
<YourComponent />
</CustomAuthenticated>
);
import CustomAuthenticated from './CustomAuthenticated';

const MyPage = () => (
<CustomAuthenticated fallback={<div>Not Authenticated</div>} loading={<div>Loading...</div>}>
<YourComponent />
</CustomAuthenticated>
);
Important Notes - Ensure that your check methods in both azureAuthProvider and customAuthProvider return promises as required by refine v4. - The custom hook and component should handle the logic for determining which auth provider to use based on the route or other parameters. For more details on the useIsAuthenticated hook and the <Authenticated /> component, you can refer to the documentation (https://refine.dev/docs/authentication/hooks/use-is-authenticated) and component guide (https://refine.dev/docs/authentication/components/authenticated). By creating custom hooks and components, you can effectively manage multiple auth providers in your refine application. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@748513525181186058> kapa.ai is still learning and improving, please let us know how it did by reacting below
distinguished-silver
distinguished-silver2mo ago
Thanks. I believe this should work. Just wanted to check if there was another way. since the check function in the authProvider can accept any parameter, here is my sample implementation:
check: async ({ domain = "" } = {}) => {
console.log(window.location.href);
const auth = Cookies.get(`auth${domain ? `-${domain}` : ""}`);
if (auth) {
return {
authenticated: true,
};
}

return {
authenticated: false,
logout: true,
redirectTo: `/login`,
};
},
check: async ({ domain = "" } = {}) => {
console.log(window.location.href);
const auth = Cookies.get(`auth${domain ? `-${domain}` : ""}`);
if (auth) {
return {
authenticated: true,
};
}

return {
authenticated: false,
logout: true,
redirectTo: `/login`,
};
},