class SessionsController < ApplicationController # 各プロバイダごとのログイン用urlを返す def login @providers = [] WeBridgeRailsEngineUsers::ProviderSettings.availables do |name| @providers << {path_method: WeBridgeRailsEngineUsers::ProviderSettings.auth_path_method(name), display: name.to_s.capitalize } end end def callback auth = request.env['omniauth.auth'] user = nil if account = UserAccount.where(provider: auth['provider'], uid: auth['uid']).first user = callback_if_account_found(account,auth) else user = callback_if_account_not_found(auth) end set_user_id(user.id) if user && !logged_in? if user else end ensure redirect_to(session[:redirect_to] || root_path) and return end def callback_if_account_found(account,auth) if logged_in? if account.user && account.user_id != current_user.id # 既に他のユーザーが使っている # ユーザーが切り替わるようにしてもいいような気がするかもしれないが、セキュリティ上のリスクを考慮して許可しないようにしている。 # 例えば、あるユーザーAは、googleアカウントとtwitterアカウントの両方でログイン可能であり、かつgoogleアカウントは他社との共有のアカウント、twitterアカウントは自分だけが使える場合、googleのアカウントでログインできる人ならだれでもAになりすますことができてしまうので危険。しかもAはそのことに気が付かない可能性が高い # error403 "#{account.provider} is used by other user." redirect_to root_path return nil # ログインユーザーが切り替わる # account.user end current_user else user = account.user if !user # if account is exists but user is deleted user = self.class.create_user_by_auth(auth) account.update(user_id: user.id) if account.user_id != user.id end user end end def callback_if_account_not_found(auth) user = nil UserAccount.transaction do if logged_in? user = current_user else user = self.class.create_user_by_auth(auth) user.text.update!(nick_name: auth.info[:name]) end UserAccount.create_with_omniauth!(auth, user.id) end user end def self.create_user_by_auth(auth) User.create!(email: auth.info[:email], user_img_url: auth.info[:image], lang_id: Lang[I18n.locale].id) end def failure flash[:notice]='login failed' redirect_to action: :login end # GET /users/logout def logout set_user_id(nil) # flash[:notice]=(logged_in? ? "logout" : "not logged in") # flash[:status]=:ok # render status: :ok, location: root_path # request.referrer[:redirect_to] || redirect_to(params["redirect_to"] || root_path) and return end end