Can one User use multiple Providers? #990
-
Hi all! I have a kind of high level/general question. I understand that I can offer multiple authentication strategies ("providers") to users during SignIn. Thanks for any ideas/pointers! 🙏 |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 4 replies
-
I just found something in the FAQ section:
Looking forward to having this supported in a future version. |
Beta Was this translation helpful? Give feedback.
-
I'd also like to implement this. Good example of what I'm thinking of is what Discord has with linking Steam, Spotify, Twitch, GitHub etc. to an existing Discord account in |
Beta Was this translation helpful? Give feedback.
-
I use the Rails doorkeeper assertion gem to help trade access_tokens for my backend API and take advantage of the signIn callback:
callbacks: {
async signIn({ user, account, profile, email, credentials }) {
if (account.provider === 'github' || account.provider === 'facebook') {
const params = { grant_type: "assertion",
client_id: "SECRET API CLIENT ID GOES HERE",
client_secret: "SECRET GOES HERE",
assertion: account.access_token,
provider: account.provider,
}
const res = await fetch("http://api:3001/oauth/token", {
method: 'POST',
body: JSON.stringify(params),
headers: { "Content-Type": "application/json" }
})
const token = await res?.json()
// If no error and we have user data, return it
if (res.ok && token) {
const user_res = await fetch("http://api:3001/api/users/current", {
method: 'GET',
headers: { "Content-Type": "application/json", "Authorization": "Bearer " + token.access_token }
})
const tsUser = await user_res.json()
user.og_account = { ...account };
user.access_token = token.access_token;
user.expires_in = token.expires_in;
user.refresh_token = token.refresh_token;
user.created_at = token.created_at;
user.access_token_expires = Date.now() + token.expires_in * 1000;
}
}
return true
},
resource_owner_from_assertion do
if server.client && params[:provider] && params[:assertion]
case params.fetch(:provider)
when "github"
auth = Doorkeeper::GrantsAssertion::OmniAuth.oauth2_wrapper(
provider: "github",
strategy_class: OmniAuth::Strategies::GitHub,
client_id: ENV["SECRET"],
client_secret: ENV["SECRET"],
client_options: { skip_image_info: false },
assertion: params.fetch(:assertion)
).auth_hash rescue nil
unless auth.nil?
# your custom finders - just like in devise omniauth
User.find_by(email: auth&.info&.email)
user = User.find_or_create_by(email: auth&.info&.email)
user.password = Array.new(25){[*"A".."Z", *"0".."9"].sample}.join if user.new_record?
user.save if user.changed?
user
end
when "facebook"
puts auth.inspect
auth = Doorkeeper::GrantsAssertion::OmniAuth.oauth2_wrapper(
provider: "facebook",
strategy_class: OmniAuth::Strategies::Facebook,
client_id: ENV["SECRET"],
client_secret: ENV["SECRET"],
client_options: { skip_image_info: false },
assertion: params.fetch(:assertion)
).auth_hash rescue nil
unless auth.nil?
# your custom finders - just like in devise omniauth
User.find_by(email: auth&.info&.email)
user = User.find_or_create_by(email: auth&.info&.email)
user.password = Array.new(25){[*"A".."Z", *"0".."9"].sample}.join if user.new_record?
user.save if user.changed?
user
end
end
end
end |
Beta Was this translation helpful? Give feedback.
I just found something in the FAQ section:
https://next-auth.js.org/faq#when-i-sign-in-with-another-account-with-the-same-email-address-why-are-accounts-not-linked-automatically
Looking forward to having this supported in a future version.