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

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

ただいまの
回答率

90.00%

Facebookログインを追加したいです(rails)

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 668

yamady

score 172

いつもお世話になっております。
Ruby(RubyonRails)チュートリアルを見ながら、作成したユーザー登録画面にFacebookログイン機能を追加したいと考えています。

いざ、登録のためにFacebookメールアドレスとパスワードを入力すると、うまくいきません。下記URLで真っ白な画面が表示されます。

http://XXXX.jp/auth/facebook/callback?code=AQBGo-1k6ip2am4LhTYw2EDseNGFlColzU9a3jDjhwx1hLQCHyeSPqqG0OGkIoqjpUP0OMhqKkzbAd5_e4dmGbRzOZawOAmMUKWd-e6hTHUGGXRn6qBbB2rt4asO4tcQJseH1wltytpf_6rEe-RCm_Oya7pJrVH8I_8JMmtPCCdLN7gWL7sh2UyIDLzw6_OgMzQ3QnGbgXMrmJ6rsHfMjln_go0kyG3kWpsYj-fhj0z_d893-JnGwJW5IGrmkpTpao8ta3ajJAV_SA6ip3IxVbRjSOhC32Ki9A26tZDMXPwdoTIZxFLKC3jvJJsVY2JLlHc&state=789ca451d73fa5358d905cc8619e4854e099169d7f4fb9d1#_=_

開発環境:Ruby on Rails 5.0.0.1

該当するソースコード

新規登録画面

<% provide(:title, "新規会員登録") %>
<section class="register">
  <%= form_for(@user, url: signup_path) do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <div class="title page-form account-form">
    <h2>新規会員登録</h2>
      <%= link_to "Facebookで登録する", "/auth/facebook", id: "sign_in", class: "btn btn-form fb-btn" %>
      <div class="form-group">
        <label for="exampleInputName">メールアドレスで登録する</label>
        <%= f.text_field :name, :placeholder => "ユーザー名", class: "form-control" %>
      </div>
      <div class="form-group">
        <%= f.email_field :email, :placeholder => "メールアドレス", class: "form-control" %>
      </div>
      <div class="form-group">
        <%= f.password_field :password, :placeholder => "パスワード", class: "form-control" %>
      </div>
      <div class="form-group">
        <%= f.password_field :password, :placeholder => "パスワードの確認", class: "form-control" %>
      </div>
      <div>
        <input type="checkbox" checked="checked"> 利用規約およびプライバシーポリシーに同意します
      </div>
      <%= f.submit "新規会員登録する", class: "btn btn-form" %>
    <% end %>
  </div>
</section>


ユーザーコントローラー

class UsersController < ApplicationController
  before_action :logged_in_user, only: [:edit, :update]
  before_action :correct_user,   only: [:edit, :update]

  def show
    @user = User.find(params[:id])
    @reviews = @user.reviews.paginate(page: params[:page], :per_page => 10)
  end

  def new
    @user = User.new
  end

  def create
    if env['ominiauth.auth'].present?
      # Facebookログイン
      @user = User.from_omniauth(env['omniauth.auth'])
      if @user.save(context: :facebook_login)
          fb = "Facebook"
          sign_in @user
          flash[:success] = "#{fb}ログインしました。"
          redirect_to url
        else
        if fb.present?
          redirect_to auth_failure_path
        else
          render 'new'
        end
      end
      else
      # 通常サインアップ
      @user = User.new(user_params)
      if @user.save
        @user.send_activation_email
        flash[:info] = "メールアドレスに確認メールをお送りしましたのでご確認ください。"
        redirect_to root_url
      else
        render 'new'
      end
    end
  end

  def edit
    @user = User.find(params[:id])
  end

  def update
    if @user.update_attributes(user_params)
      flash[:success] = "プロフィールを更新しました"
      redirect_to @user
    else
      render 'edit'
    end
  end

  private

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

  # beforeアクション

  # 正しいユーザーかどうか確認
  def correct_user
    @user = User.find(params[:id])
    redirect_to(root_url) unless current_user?(@user)
  end
end


ユーザーモデル

class User < ApplicationRecord
  has_many :reviews, dependent: :destroy
  attr_accessor :remember_token, :activation_token, :reset_token
  before_save :downcase_email
  before_create :create_activation_digest
  validates :name, presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
  validates :email, presence:   true, length: { maximum: 255 },
                    format:     { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
  validates :background, length: { maximum: 50 }
  has_secure_password
  validates :password, presence: true, length: { minimum: 6 }, allow_nil: true
  validates :password, presence: false, on: :facebook_login
  mount_uploader :image, ImageUploader

  # 渡された文字列のハッシュ値を返す
  def User.digest(string)
    cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
                                                  BCrypt::Engine.cost
    BCrypt::Password.create(string, cost: cost)
  end

  # ランダムなトークンを返す
  def User.new_token
    SecureRandom.urlsafe_base64
  end

  # 永続セッションのためにユーザーをデータベースに記憶する
  def remember
    self.remember_token = User.new_token
    update_attribute(:remember_digest, User.digest(remember_token))
  end

  # 渡されたトークンがダイジェストと一致したらtrueを返す
  def authenticated?(attribute, token)
    digest = send("#{attribute}_digest")
    return false if digest.nil?
    BCrypt::Password.new(digest).is_password?(token)
  end

  # ユーザーのログイン情報を破棄する
  def forget
    update_attribute(:remember_digest, nil)
  end

  # アカウントを有効にする
  def activate
    update_attribute(:activated,    true)
    update_attribute(:activated_at, Time.zone.now)
  end

  # 有効化用のメールを送信する
  def send_activation_email
    UserMailer.account_activation(self).deliver_now
  end

  # パスワード再設定の属性を設定する
  def create_reset_digest
    self.reset_token = User.new_token
    update_attribute(:reset_digest, User.digest(reset_token))
    update_attribute(:reset_sent_at, Time.zone.now)
  end

  # パスワード再設定のメールを送信する
  def send_password_reset_email
    UserMailer.password_reset(self).deliver_now
  end

  # パスワード再設定の期限が切れている場合はtrueを返す
  def password_reset_expired?
    reset_sent_at < 2.hours.ago
  end

  # Facebookログイン
  def self.from_omniauth(auth)
    # emailの提供は必須とする
    user = User.where('email = ?', auth.info.email).first
  if user.blank?
    user = User.new
  end
    user.uid   = auth.uid
    user.name  = auth.info.name
    user.email = auth.info.email
    user.image  = auth.info.image
    user.oauth_token      = auth.credentials.token
    user.oauth_expires_at = Time.at(auth.credentials.expires_at)
    user
  end

  def feed
    Review.where("user_id = ?", id)
  end

  private

    # メールアドレスをすべて小文字にする
    def downcase_email
      self.email = email.downcase
    end

    # 有効化トークンとダイジェストを作成および代入する
    def create_activation_digest
      self.activation_token  = User.new_token
      self.activation_digest = User.digest(activation_token)
    end
end

コンソールのエラー

イメージ説明

コンソール上では上記のようなエラーが表示されています。

gem Deviceを使うべきなのでしょうか?
既存のUserモデルに追加したいので、非常に困っています・

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • gouf

    2017/05/19 14:28

    Web ブラウザの開発者コンソールになにかエラーは表示されていますか

    キャンセル

  • yamady

    2017/05/19 16:15

    コメントありがとうございます!コンソールのエラーを追記しました!

    キャンセル

回答 1

check解決した方法

0

deviseで作りなおすことにしました。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

同じタグがついた質問を見る