Я работаю над аутентификацией пользователей в социальных сетях, используя Devise и Omniauth. Я добавил следующее к своему config/initializers/devise.rb
:
config.omniauth :facebook, ENV['FACEBOOK_APP_ID'], ENV['FACEBOOK_APP_SECRET'], scope: 'public_profile,email', callback_url: "#{ENV['SERVER_ROOT']}/users/auth/facebook/callback"
config.omniauth :google_oauth2, ENV['GOOGLE_APP_ID'], ENV['GOOGLE_APP_SECRET'], scope: 'userinfo.email,userinfo.profile', redirect_uri: "#{ENV['SERVER_ROOT']}/users/auth/google_oauth2/callback"
config.omniauth :twitter, ENV['TWITTER_APP_ID'], ENV['TWITTER_APP_SECRET'], callback_url: "#{ENV['SERVER_ROOT']}/users/auth/twitter/callback"
config.omniauth :instagram, ENV['INSTAGRAM_APP_ID'], ENV['INSTAGRAM_APP_SECRET'], callback_url: "#{ENV['SERVER_ROOT']}/users/auth/instagram/callback"
а по моему app/controllers/omniauth_callbacks_controller.rb
:
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def all
user = User.from_omniauth(request.env["omniauth.auth"])
if user.persisted?
sign_in_and_redirect user, notice: "Signed in!"
else
session["devise.user_attributes"] = user.attributes
redirect_to new_user_session_url
end
end
alias_method :twitter, :all
alias_method :google_oauth2, :all
alias_method :facebook, :all
alias_method :instagram, :all
end
end
В app/models/users.rb
Я добавил:
class User < ApplicationRecord
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable,
:omniauthable
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.provider = auth.provider
user.email = auth.info.email || if auth.info.nickname then auth.info.nickname + "@twitter.org" end
user.uid = auth.uid
user.skip_confirmation!
end
end
def self.new_with_session(params, session)
if session["devise.user_attributes"]
new(session["devise.user_attributes"], without_protection: true) do user
user.attributes = params
user.valid?
end
else
super
end
end
def password_required?
super && provider.blank?
end
end
Я также настроил приложения социальных сетей (или клиентов) для перенаправления на https://<my domain name>/users/auth/<social media>/callback
Теперь я могу войти через Facebook и Google. Однако Twitter перенаправляет на:
https://api.twitter.com/users/auth/twitter/callback?oauth_token=<some token> with message "Sorry, that page doesn’t exist!" (not the callback url).
и Instagram перенаправляет на:
https://www.instagram.com/oauth/authorize?client_id=<client id>&redirect_uri=/users/auth/instagram/callback&response_type=code&scope=basic&state=<some state number>
с ответом JSON:
{"error_type": "OAuthException", "code": 400, "error_message": "Redirect URI does not match registered redirect URI"}
Примечание: URL-адрес обратного вызова, который я ввел в своем приложении Twitter, - https://<my domain>/users/auth/twitter/callback
и URI перенаправления, который я ввел в своем клиенте Instagram, составляет https://<my domain>/users/auth/instagram/callback
Я изменил строку Instagram в config/initializers/devise.rb
на:
config.omniauth :instagram, ENV['INSTAGRAM_APP_ID'], ENV['INSTAGRAM_APP_SECRET'], redirect_uri: "#{ENV['SERVER_ROOT']}/users/auth/instagram/callback"
Однако аутентификация также перенаправляет на:
https://www.instagram.com/oauth/authorize?client_id=<client id>&redirect_uri=/users/auth/instagram/callback&response_type=code&scope=basic&state=<some state number>