JudahGabriel / RavenDB.Identity

RavenDB Identity provider for ASP.NET Core. Let RavenDB manage your users and logins.
https://www.nuget.org/packages/RavenDB.Identity/1.0.0
MIT License
61 stars 29 forks source link

How to handle unique constraints in a user? #28

Closed cadilhac closed 4 years ago

cadilhac commented 4 years ago

Hi,

I'm new to both asp.net core identity and your project and I was wondering how to tackle the need for unique constraints, for example for the username. At what level can it be done? Thanks

JudahGabriel commented 4 years ago

In short, you don't have to do anything on the backend. RavenDB.Identity will enforce email-based uniqueness on the cluster level. If a user tries to register with an already-registered email address, the 2nd attempt will fail.

Does that answer your question?

cadilhac commented 4 years ago

No ;) I know that you take care about email uniqueness. My question is about having some other fields unique, in particular the username.

cadilhac commented 4 years ago

And the question can be extended to a field that is not in the user's base class. It's not my use case, but it could be a custom field that I will add in my user's derived class.

JudahGabriel commented 4 years ago

For uniqueness, you'll want to use Raven's compare/exchange functionality.

This is what RavenDB.Identity does under the hood: when a user is about to be created, it tries to set a compare/exchange value with the unique field as the key, e.g. "Users/rickastley". If setting the compare/exchange value succeeds, it's unique.

For user name, we do have a in-progress PR that lets you configure RavenDB.Identity to store by user name, rather than email. It's not quite ready to be merged, though.

cadilhac commented 4 years ago

Well, the PR is by ID like 33-A, not by username. So if I want to have a specific field unique, I'll have to modify your code which is not a great solution but it seems this is what I'll have to do. It would have been great if this was a generic feature of this library.

JudahGabriel commented 4 years ago

You're right, the PR is for generated ID, rather than username or email.

I don't think you need to modify our code. Rather, in your own registration code, before calling CreateUserAsync, do you uniqueness check using compare/exchange. That's all you need to do, really.

cadilhac commented 4 years ago

Good idea. I can encapsulate the call to your API with a reserve, and unreserve if it failed.