access control caching

Hi, the caching of access control provider does not seem to work. The caching in general works (for resource fetching) and I have explicitly defined the cache and stale parameters for accessControlProvider, but on navigation to a different menu I see that my custom accessControlProver gets called every time. Is this expected?
7 Replies
kapa.ai
kapa.ai3mo ago
Hi @duneatnight. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- The behavior you're experiencing with the access control provider being called every time you navigate to a different menu might indeed be expected, depending on how you've implemented or configured caching for your access control checks. Refine uses react-query for data fetching and caching, and this includes the capability to cache access control checks to improve performance. However, the effectiveness of this caching can depend on how you've configured the staleTime and cacheTime properties for your access control checks. As per the information provided in the extracts, Refine allows you to configure caching for access control checks using the staleTime and cacheTime properties through react-query's useQuery options. By default, Refine uses 5 minutes for cacheTime and 0 minutes for staleTime for its own access control points. If you've set these properties explicitly but are still experiencing issues with caching not working as expected, it's possible that the issue might lie elsewhere in your implementation or configuration. Here's an example of how you might configure the staleTime for an access control check, as mentioned in the extracts:
// inside your component

const { data } = useCan({
resource: "resource-you-ask-for-access",
action: "action-type-on-resource",
params: { foo: "optional-params" },
queryOptions: {
staleTime: 5 * 60 * 1000, // 5 minutes
// ... other query options
},
});
// inside your component

const { data } = useCan({
resource: "resource-you-ask-for-access",
action: "action-type-on-resource",
params: { foo: "optional-params" },
queryOptions: {
staleTime: 5 * 60 * 1000, // 5 minutes
// ... other query options
},
});
This configuration should cache the result of the access control check for 5 minutes, reducing the number of times the access control provider needs to be called. If you're still facing issues despite this configuration, it might be helpful to review the rest of your implementation to ensure that it aligns with Refine's best practices for using the access control provider and react-query. For more detailed information on configuring and using the access control provider in Refine, including performance considerations, you can refer to the official documentation: Access Control Provider Performance (https://refine.dev/docs/authorization/access-control-provider#performance). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@1051552034823872643> kapa.ai is still learning and improving, please let us know how it did by reacting below
foreign-sapphire
foreign-sapphire3mo ago
Figured it out myself. RefineKbar was messing things up. This should be mentioned in documentation or at least not injected by default when scaffolding.
harsh-harlequin
harsh-harlequin3mo ago
Hello @duneatnight, Can you please explain in more detail what kind of problem RefineKbar caused?
foreign-sapphire
foreign-sapphire3mo ago
The caching for accessControlProvider seems not to work This is my AccessControlProvider: import { AccessControlProvider, CanParams } from "@refinedev/core"; import { CanResponse } from "@refinedev/core/dist/interfaces/bindings/access-control"; import { hasExternalRole } from "./externalRoleProvider"; export const createAccessProvider = (): AccessControlProvider => { return { can: async ({ resource, action, params, }: CanParams): Promise<CanResponse> => { console.log("Access for ", resource, " with action ", action); if (resource === "tenants") { const can = await hasExternalRole("root"); return Promise.resolve({ can, }); } return Promise.resolve({ can: true, }); }, options: { buttons: { enableAccessControl: false, hideIfUnauthorized: false, }, queryOptions: { staleTime: 5 * 60 * 1000, }, }, }; }; With RefineKBar and RefineKBarProvider that is wrapping my Refine component in App.tsx it gets called every time I navigate in the menu. If I remove KBar it gets called once like it should.
foreign-sapphire
foreign-sapphire3mo ago
GitHub
refine/packages/kbar/src/hooks/useRefineKbar/index.tsx at 1b1462579...
A React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility. - refinedev/refine
harsh-harlequin
harsh-harlequin3mo ago
It's possible, thank you for pointing this issue. I will discuss with the core team