-
-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Social Authentication, when user already exists #154
Comments
Thanks!
Can you help me understand the exact state the user is in here? They were invited, clicked the link, update with password, and then they try to sign in with google after? And is It sounds like the issue experienced in #113 and I'm thinking of resolving like #115. |
For sure. The state of the user:
It used to just error out on Repo.Insert into users, but now it handles error (Not sure if it is due to recent update)
It seems to rollback transaction now on error. Basically social login will always fail if user already exists in database in "users" table but has no identity assigned in "user_identities" thank you Edit: It looks like a similar issue to the ones you referenced, but I am not 100% sure. What I am struggling to understand, is that authentication through google works fine if user already exists in "users" table (was invited) AND query string contains "invitation token". Then POW does not try to insert user, but only inserts user_identity, and works correctly. |
It's because when the user follows the invite link, the struct is already loaded in the conn, so it's in an "authenticated" state and the identity will be upserted. The same happens when a user is authenticated and then links a provider. When there's no user in the conn the logic will instead attempt to create identity and user at the same time. This is the same as discussed in the linked issues. So a constraint error will occur and the user is redirected to set the e-mail manually. I think permitted verified provider emails to automatically link up with the user could work, but really #115 is the best solution. Ideally you have to authenticate with an existing method for your account before you can add a new auth method. I hope I can open a PR to do this very soon. If you want to do something similar to the above, then I would recommend that you create a custom controller overriding the |
Thank you very much for your help. |
@danschultzer As this issue is open, I will add another scenario here that I came across related to social auth. I'm using both pow & pow_assent for api only authentication. I have set user_id_field: :username on my user schema. First I created a user using username say 'akash' along with email/password which worked just fine. The issue comes when I'm trying to register another account with oauth (discord in this case). The discord account returns the same username This throws a unique constraint error (users_username_index) as a user with How can I handle such cases? (I think probability of this occuring is high with discord as discord allows having same username for multiple users and differentiate with username#12123, but returns only the part before # in oauth callback flow). I'm not sure how to handle it within my user model, would always doing a update_change on username field to add random string (and allow the user to change username later ) in the assent changeset (user_identity_changset) be a good idea? |
Yeah, this would be the easiest solution! It's not great though, what would be better UX would be that the user corrects the username themselves. This goes together with the refactor I want to do with #195 #170 and this one, to allow for more dynamic handling of changeset errors. Ideally any errors that the end-user can fix should be displayed to them, and anything apart from that should result in redirect error. |
Thanks, my current implementation is to add a random string with # prefix and complete the upsert as I did not see any way to take additional input from user with the api and keep the oauth flow going. I am adding additional logic on frontend to redirect user to change username if it is marked to change. |
Hi! First thank you very much for the library, pretty much the only authentication for phoenix.
I am experiencing some difficulties with authentication flow using social providers when user already exists. Let me know if I am wrong, but pretty much steps to reproduce:
I have below extensions installed:
In my app, users can invite other users. This flow seems to be working correctly. Once user invites another one, they receive email. Here is where it breaks for me:
User has 2 ways of continuing after confirming email:
As long as users use the same method to login, the way they logged in first, there are no problems.
After some digging, the flow for authentication or upsert is done in PowAssent.Plug:
Up until maybe_authenticate call everything works correctly. But "authenticate" call only tries to pull user from user_identities and not from users. Thus user is not found and nil is returned. Since authentication failed, assent tries to insert user, but failes, since user exists in "users" table but not in "user_identities" table.
authenticate code:
Thank you very much, please let me know if I am wrong somewhere.
The text was updated successfully, but these errors were encountered: