leonibr / community-extensions-cache-postgres

A PostgreSQL Implementation of IDistributedCache interface. Using Postgresql as distributed cache in Asp.Net Core. NetStandard 2.0
54 stars 17 forks source link

Configure several instances of cache #15

Closed MargaretKrutikova closed 2 years ago

MargaretKrutikova commented 2 years ago

Is there any way to setup several instances of postgres distributed cache? We need to have several tables in different schemas that should function as cache, each having different expiration time and other options. Is it possible to achieve this with the current design and dotnet DI? Thanks!

leonibr commented 2 years ago

Hello there, This is not the default way of using any .Net Cache implementation (in-Memory, Redis, NCache, SQL Server, PostgreSQL). You don't turn a regular business table into a "Cache Table" you pull the data from the hot table and store it in cache with a meaningful key you can use later to retrieve the data.

MargaretKrutikova commented 2 years ago

Thanks for your response!

I am not sure I understand/agree with you here. I am using Postgres to cache user tokens when authenticating them against Microsoft and now I need to implement support for state parameter in oauth2 code flow, which I was planning to store in another cache in Postgres. Does that look like a weird scenario? Do you have an idea on how to solve it following the default dotnet way?

leonibr commented 2 years ago

Hi, Sorry I didn't quite understand you well, our implementation is meant to be used on servers, is a classical distributed cache, but let me try to understand what you said piece by piece:

I am using Postgres to cache user tokens when authenticating them against Microsoft

Since you mentioned Oauth2 later on I believe you are talking about JWT tokens ? These shouldn't be stored on client's device (browser, native app, iot, etc) rather than on server (Cache/Postgres/.net api). ...but if you must store some sort of tokens on the server, it is fine. 🦅 Is this part already working?

now I need to implement support for state parameter in oauth2 code flow

This is how Auth0 explains state parameters

The primary reason for using the state parameter is to mitigate CSRF attacks by using a unique and non-guessable value associated with each authentication request about to be initiated. That value allows you to prevent the attack by confirming that the value coming from the response matches the one you sent. The state parameter is a string so you can encode any other information in it. You send a random value when starting an authentication request and validate the received value when processing the response. You store something on the client application side (in cookies, session, or localstorage) that allows you to perform the validation. If you receive a response with a state that doesn't match, you can infer that you may be the target of an attack because this is either a response for an unsolicited request or someone trying to forge the response.

That been said, state parameter is not supposed to be stored on the server because every request should have his own unique state parameter, and that lead us to:

which I was planning to store in another cache in Postgres

Every instance of your application will use the same IDistributedCache implementation across the instance, and if all instances point to the same database they all will share the same data. 🥳

Do you have an idea on how to solve it following the default dotnet way?

This is not a .Net thing... this is an architectural pattern that can be used for any programming language and database.

I am sorry if I couldn't be clear enough... 😢

and please do not hesitate in asking again!

MargaretKrutikova commented 2 years ago

Hello! Thanks for your response, you were very clear 🙂 We have a pretty weird hybrid setup with MS authentication, and it is not client side, everything is done on the server.

I had an epiphany moment yesterday and realised that it is the same cache that is used for caching different "groups" of data. Like it would be weird to ask the same question for memory cache, "can I have one memory to cache users and another memory to cache products"? It is just one memory 🙂 I also found that SetStringAsync on IDistributedCache allows passing in options with sliding expiration time and other settings which allows me to have some logical separation between the data cached (tokens and state values). Again, thanks for the detailed response, the missing part was that all logical "groups" of the cached data are stored in one table where you can have separate abstractions for these logical groups with the settings you want for that specific group.