質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.00%

Facebook認証が通りません(rails)

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 2,053

yamady

score 172

前提・分からないこと

いつもお世話になっております。
teratailさまにいつも、助けられています。

独学で進めてきたRuby on Railsによるサイト制作も個人の完成として、一つの区切りを迎えることができました。まず、本当にありがとうございます。
お手すきの際に、ご教示いただけると嬉しいです。

開発環境:Ruby on Rails 5.0.0.1
利用しているgem:Devise

Deviseを使って、Facebook認証をしようとしています。
エラーメッセージはおそらく、Deviseに設定されているヘルパーだとは思いますが、どうやってもこのエラーが出てしまい、Facebook認証が成功しません。

Could not authenticate you from Facebook because "Invalid credentials".


そのほか、質問者さまの投稿や、Web投稿をみて、いろいろ試してみましたが、うまくいかず。。

下記のURLを参考にしながら進めました。
http://ticklecode.com/fb_omniauth/

該当するソースコード

user.rb

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :lockable, :timeoutable
  devise :database_authenticatable, :registerable, :confirmable,
         :recoverable, :rememberable, :trackable, :validatable, :omniauthable
  mount_uploader :image, ImageUploader
  validates :name, uniqueness: { case_sensitive: :false }, length: { minimum: 4, maximum: 20 }
  has_many :reviews

  def self.find_for_oauth(auth)
    user = User.where(uid: auth_uid, provider: auth.provider).first

    unless user
      user = User.create(
        uid:        auth.uid,
        provider:   auth.provider,
        email:      User.dummy_email(auth),
        password:   Devise.friendly_token[0, 20]
      )
    end

    user
  end

  def self.find_first_by_auth_conditions(warden_conditions)
    conditions = warden_conditions.dup
    if login = conditions.delete(:login)
      where(conditions).where(["name = :value OR lower(email) = lower(:value)", { :value => login }]).first
    else
      where(conditions).first
    end
  end

  private

  def user_params
    params.require(:user).permit(:name, :email, :password, :password_confirmation, :image, :background)
  end

  def self.dummy_email(auth)
    "#{auth.uid}-#{auth.provider}@example.com"
  end
end

users/omniauth_callbacks_controller.rb

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def facebook
    callback_from :facebook
  end

  private

  def callback_from(provider)
    provider = provider.to_s

    @user = User.find_for_oauth(request.env['omniauth.auth'])

    if @user.persisted?
      flash[:notice] = I18n.t('devise.omniauth_callbacks.success', kind: provider.capitalize)
      sign_in_and_redirect @user, event: :authentication
    else
      session["devise.#{provider}_data"] = request.env['omniauth.auth']
      redirect_to new_user_registration_url
    end
  end
end

routes.rb

Rails.application.routes.draw do

  get 'users/show'

  devise_for :users, controllers: { registrations: 'users/registrations',
    omniauth_callbacks: 'users/omniauth_callbacks',
    sessions: 'users/sessions', confirmations: 'users/confirmations',
    passwords: 'users/passwords'
    }
  devise_scope :user do
    get '/users/sign_out', to: 'users/sessions#destroy'
  end
end

Devise.rb

# Use this hook to configure devise mailer, warden hooks and so forth.
# Many of these configuration options can be set straight in your model.
Devise.setup do |config|
  require 'devise/orm/active_record'
・・・
  # ==> Mountable engine configurations
  # When using Devise inside an engine, let's call it `MyEngine`, and this engine
  # is mountable, there are some extra configurations to be taken into account.
  # The following options are available, assuming the engine is mounted as:
  #
  #     mount MyEngine, at: '/my_engine'
  #
  # The router that invoked `devise_for`, in the example above, would be:
  # config.router_name = :my_engine
  #
  # When using OmniAuth, Devise cannot automatically set OmniAuth path,
  # so you need to do it manually. For the users scope, it would be:
  # config.omniauth_path_prefix = '/my_engine/users/auth'
  config.secret_key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  require "omniauth-facebook"
  config.omniauth :facebook, ENV['APP_ID'], ENV['APP_SECRET']
end

omniauth.rb

Rails.application.config.middleware.use OmniAuth::Builder do
end

環境変数は本番環境に設定済みです。

$ heroku config
=== サーバー名 Config Vars
APP_ID:    XXXXXXXXXXXXXXXX
APP_SECRET:     XXXXXXXXXXXXXXXXXXXXX

追記

user.rb

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :lockable, :timeoutable
  devise :database_authenticatable, :registerable, :confirmable,
         :recoverable, :rememberable, :trackable, :validatable, :omniauthable, omniauthable: [:facebook]
  mount_uploader :image, ImageUploader
  validates :name, uniqueness: { case_sensitive: :false }, length: { minimum: 4, maximum: 20 }
  has_many :reviews
  attr_accessible :provider, :uid

  def self.find_for_oauth(auth)
    user = User.where(uid: auth_uid, provider: auth.provider).first

    unless user
      user = User.create(
        uid:        auth.uid,
        provider:   auth.provider,
        email:      User.dummy_email(auth),
        token:    auth.credintials.token,
        password:   Devise.friendly_token[4, 30]
      )
    end

    user
  end

  def self.find_first_by_auth_conditions(warden_conditions)
    conditions = warden_conditions.dup
    if login = conditions.delete(:login)
      where(conditions).where(["name = :value OR lower(email) = lower(:value)", { :value => login }]).first
    else
      where(conditions).first
    end
  end

  private

  def user_params
    params.require(:user).permit(:name, :email, :password, :password_confirmation, :image, :background)
  end

  def self.dummy_email(auth)
    "#{auth.uid}-#{auth.provider}@example.com"
  end
end


attr_accessible :provider, :uidや、omniauthable: [:facebook]を追記しました。

token_params: { parse: :json }を追記しました。

追記その2

ominiauthのバージョンがよくないのかと思い、

gem 'omniauth-facebook', '1.4.0'


に落としてみました。ですが、やはり通りません。。
どうなっているんでしょうかね。。。。

追記その3

Facebookアプリ側の記載をします。

イメージ説明

イメージ説明

イメージ説明

「アイテムを審査に送信」も今回の件は必要なさそうですよね。。。

追記その4

ボタンを押すと、下記でFacebookログインが求められますが。。
イメージ説明

ログインするとエラーメッセージとなってしまいます。
イメージ説明

ログイン後の対応がよくないのでしょうか。。

追記その4【更新版】

Gemfile

source 'https://rubygems.org'
・・・
gem 'dotenv-rails'
gem 'omniauth-facebook', '1.4.0'
・・・
group :production do
  gem 'pg', '0.18.4'
end

# Windows環境ではtzinfo-dataというgemを含める必要があります
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]


$gem list

・・・
multipart-post (2.0.0)
nenv (0.3.0)
nio4r (2.0.0, 1.2.1)
nokogiri (1.7.2, 1.7.1, 1.6.7.2)
notiffany (0.1.1, 0.0.8)
orm_adapter (0.5.0)
pg (0.18.4)
・・・


gemfile.lock

・・・
    notiffany (0.1.1)
      nenv (~> 0.1)
      shellany (~> 0.0)
    oauth2 (0.6.1)
      faraday (~> 0.7)
      httpauth (~> 0.1)
      multi_json (~> 1.3)
    omniauth (1.6.1)
      hashie (>= 3.4.6, < 3.6.0)
      rack (>= 1.6.2, < 3)
    omniauth-facebook (1.4.0)
      omniauth-oauth2 (~> 1.0.2)
    omniauth-oauth2 (1.0.2)
      oauth2 (~> 0.6.0)
      omniauth (~> 1.0)

DEPENDENCIES
・・・
  devise
  dotenv-rails
  geocoder
  gmaps4rails
  google-analytics-rails
  guard (= 2.13.0)
  guard-minitest (= 2.4.4)
  jbuilder (= 2.4.1)
  jquery-rails (= 4.1.1)
  listen (= 3.0.8)
  mini_magick
  minitest-reporters (= 1.1.9)
  omniauth-facebook (= 1.4.0)
  pg (= 0.18.4)
  puma (= 3.4.0)
  rails (= 5.0.0.1)
  rails-controller-testing (= 0.1.1)
  ransack
  rmagick
  sass-rails (= 5.0.6)
  spring (= 1.7.2)
  spring-watcher-listen (= 2.0.0)
  sqlite3 (= 1.3.11)
  turbolinks (= 5.0.1)
  tzinfo-data
  uglifier (= 3.0.0)
  web-console (= 3.1.1)
  will_paginate (= 3.1.0)

BUNDLED WITH
   1.12.1

追記その5

下記、参考に「devise.rb」のパスワードを直してみましたが効果なしでした。。
http://abeyuusuke1978.hatenablog.com/entry/2015/01/03/235255

devise.rb

Devise.setup do |config|
  config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
  require 'devise/orm/active_record'
  config.case_insensitive_keys = [:email]
  config.strip_whitespace_keys = [:email]
  config.skip_session_storage = [:http_auth]
  config.stretches = Rails.env.test? ? 1 : 11
  config.reconfirmable = true
  config.expire_all_remember_me_on_sign_out = true
  config.password_length = 4..30
  config.email_regexp = /\A[^@\s]+@[^@\s]+\z/
  config.reset_password_within = 6.hours
  config.sign_out_via = [:get, :delete]
  config.secret_key = 'XXXXXXXXXXXXX'
  require "omniauth-facebook"
  config.omniauth :facebook, ENV['APP_ID'], ENV['APP_SECRET'],token_params: { parse: :json }
end

なんでなんだ・・・・涙

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

Facebook API version >=2.3からtoken_params: { parse: :json }と言うパラメータが必要なようです。

config.omniauth :facebook, ENV['APP_ID'], ENV['APP_SECRET'],token_params: { parse: :json }


stackoverflow
ちなみに私は翻訳家では無いので
エラー名でググってかじりついて読んでみましょう。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/24 11:43

    gemfileは追記しました、文字数制限があり一部鹿できませんでしたが。。。



    キャンセル

  • 2017/05/25 08:35

    omniauth-oauth2を1.3.1にするんですよ
    念のため

    キャンセル

  • 2017/05/26 13:43

    ありがとうございます!もう少し頑張ってやってみます。。
    できましたら、こちらに報告いたします!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.00%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる