Невозможно получить рельсы OmniAuth для работы Google с devise
Я использую гем "omniauth-google-oauth2" для настройки входа в Google наряду с разработкой имени для входа. Также добавлен ssl в корневой каталог приложения, как упомянуто в руководстве (File => cacert.pem)
В /config/initializers/omniauth.rb
OmniAuth.config.logger = Rails.logger
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2,"google_clent_id", "google_secret_id",{client_options: {ssl: {ca_file:Rails.root.join("cacert.pem").to_s}}}
end
В /config/initializers/devise.rb
config.omniauth :google_oauth2, "google_client_id", "google_secret_id", { name: 'google' }
В routes.rb
devise_for :users, :controllers => { sessions: "sessions", registrations: 'registrations',:omniauth_callbacks => "users/omniauth_callbacks" }
get 'auth/:provider/callback', to: 'sessions#create'
get 'auth/failure', to: redirect('/')
get 'signout', to: 'sessions#destroy', as: 'signout'
В controllers/users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
skip_before_action :verify_authenticity_token
def google_oauth2
@user = User.from_omniauth(request.env["omniauth.auth"])
if @user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Google"
sign_in_and_redirect @user, :event => :authentication
else
session["devise.google_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
end
В user.rb
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :omniauthable,
:omniauth_providers => [:google_oauth2]
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_initialize.tap do |user|
user.provider = auth.provider
user.uid = auth.uid
full_name = auth.info.name.split(" ")
user.first_name = full_name[0]
user.last_name = full_name[1]
user.email = auth.info.email
user.oauth_token = auth.credentials.token
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.save!
end
end
В sessions_controller.rb
def create
user = User.from_omniauth(env["omniauth.auth"])
session[:user_id] = user.id
redirect_to root_path
end
def destroy
session[:user_id] = nil
redirect_to root_path
end
На мой взгляд (html.erb файлы)
<% if current_user %>
Signed in as <strong><%= current_user.name %></strong>!
<%= link_to "Sign out", signout_path, id: "sign_out" %>
<% else %>
<%= link_to "Sign in with Google", user_google_oauth2_omniauth_authorize_path, id: "sign_in" %>
<% end %>
Когда я нажимаю на ссылку для входа, я перенаправляюсь на страницу выбора аккаунта Google. Когда я вхожу с учетной записью, страница перенаправляется на корневой путь, но пользователь не выполнил вход. Но данные пользователя были зарегистрированы в таблице пользователей базы данных. И журнал сервера показан ниже:
Started GET "/users/auth/google_oauth2" for 127.0.0.1 at 2018-01-21 15:49:11 +0530
(0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
(google_oauth2) Request phase initiated.
Started GET "/users/auth/google_oauth2/callback?state=*****&code=4/****" for 127.0.0.1 at 2018-01-21 15:49:16 +0530
(google_oauth2) Callback phase initiated.
Processing by Users::OmniauthCallbacksController#google_oauth2 as HTML
Parameters: {"state"=>"****", "code"=>"4/****"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."provider" = ? AND "users"."uid" = ? ORDER BY "users"."id" ASC LIMIT ? [["provider", "google_oauth2"], ["uid", "*****"], ["LIMIT", 1]]
(0.1ms) begin transaction
SQL (3.5ms) UPDATE "users" SET "oauth_token" = ?, "oauth_expires_at" = ?, "updated_at" = ? WHERE "users"."id" = ? [["oauth_token", "*********"], ["oauth_expires_at", "2018-01-21 11:19:16"], ["updated_at", "2018-01-21 10:19:17.882842"], ["id", 2]]
(105.7ms) commit transaction
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 2], ["LIMIT", 1]]
Redirected to http://localhost:3000/
Completed 302 Found in 220ms (ActiveRecord: 111.1ms)
Started GET "/" for 127.0.0.1 at 2018-01-21 15:49:18 +0530
Processing by HomeController#index as HTML
Rendering home/index.html.erb within layouts/application
Rendered layouts/sliders/_slider_home.html.erb (0.4ms)
Rendered customers/_index.html.erb (1.6ms)
Rendered home/index.html.erb within layouts/application (3.4ms)
Rendered layouts/header/_style_files.html.erb (0.3ms)
Rendered layouts/_meta_files.html.erb (1.5ms)
Rendered layouts/logos/_logo_main.html.erb (1.4ms)
Rendered layouts/header/_header_search.html.erb (2.5ms)
Rendered layouts/header/_header_navigation.html.erb (0.6ms)
Rendered layouts/logos/_logo_secondary.html.erb (1.1ms)
Rendered layouts/footer/_footer.html.erb (2.3ms)
Rendered layouts/static/_hover_top.html.erb (0.4ms)
Rendered layouts/footer/_script_files.html.erb (1.1ms)
Completed 200 OK in 727ms (Views: 724.5ms | ActiveRecord: 0.0ms)
В целях безопасности некоторые поля помечены звездочками (****). Информация о пользователе сохраняется в таблице "пользователи" в базе данных, даже не спрашивая никаких разрешений. Но почему пользователь не входит в систему? Мои обычные формы входа в систему также не работают. Пожалуйста, помогите понять, что я здесь делаю не так? Заранее спасибо.
2 ответа
Если кто-то отстает, для меня проблема заключалась в том, что мне не хватало 1.9.1 в моем гем-файле. Добавление этого устранило проблему для меня. Я часами проверял свой код на предмет опечаток, но все время это было жемчужиной.
gem "omniauth", "~> 1.9.1"gem "omniauth-google-oauth2"
Ваш код выглядит довольно хорошо. Но я думаю в routes.rb
Вы должны добавить обратный вызов в качестве дополнительного параметра
devise_for :users, controllers: {
omniauth_callbacks: 'users/omniauth_callbacks'
}
и привязать или создать пользователя
def self.from_omniauth(access_token)
data = access_token.info
user = User.where(email: data['email']).first
# Uncomment the section below if you want users to be created if they don't exist
# unless user
# user = User.create(name: data['name'], # email: data['email'],
# password: Devise.friendly_token[0,20] # )
# end
user
end
Не используйте эту конфигурацию в
config/initializers/omniauth.rb:
Rails.application.config.middleware.use
OmniAuth::Builder do
provider :google_oauth2,
ENV['GOOGLE_CLIENT_ID'],
ENV['GOOGLE_CLIENT_SECRET']
end
определить идентификатор приложения и секрет в
config/initializers/devise.rb
Для дополнительных разрешений вы можете использовать
Rails.application.config.middleware.use
OmniAuth::Builder do
provider :google_oauth2,
ENV['GOOGLE_CLIENT_ID'],
ENV['GOOGLE_CLIENT_SECRET'],
{
name: 'google',
scope: 'email, profile, plus.me, http://gdata.youtube.com',
prompt: 'select_account',
image_aspect_ratio: 'square',
image_size: 50
}
конец
если вы измените
config.omniauth :google_oauth2,
ENV["GOOGLE_ID"],
ENV["GOOGLE_SECRET"]
Сервер даже не запустится. Однако проблема, казалось, была в переданном параметре к этому в
config.omniauth :google_oauth2, ENV["GOOGLE_ID"], ENV["GOOGLE_SECRET"],
{ :name => "google", # this is the line that was giving me trouble
:scope => "email",
:prompt => "select_account",
:image_aspect_ratio => "square",
:image_size => 50 }
Я думаю, что вы изменяете способ, которым был возвращен аутентификации, т.е.
:google => {:name => "foo", :email => "bar@email.com" }
изменение и затем несоответствие маршрутов. Устройство, созданное
user_google_oauth2_omniauth_authentication_path
все еще указывает на
users/auth/google_oauth2/authentication
но отмеченная строка в аргументах заставила Оаут ожидать
users/auth/google/authentication