SNS認証 facebookだけ通らなかった原因


前提

  • 今回、sns認証(google, facebook)を実装していました。
  • そこで、googleは既存のusersテーブルと紐づくのに、facebookだけ認証が通らないエラーが発生しましたので、原因を記録します。(そのため、sns認証の細かい実装方法に関しては割愛します。)
  • 原因は判明しましたが、根本的な解決には至っていませんので、あくまで原因を探す参考程度にご覧ください。

実行環境

rails 6.0.0

mysql 5.6.47

エラーの内容

 今回、snsの認証とともに、userの情報を紐付けて保存する仕様にしていました。
ところがログインしようとすると、、、

おかしい、、、
Googleでは確かにログインができるのに、Facebookでは新規登録画面へ飛ばされてしまいました。

原因

原因は、user.rbにありました。apiから送られてくるデータの検索方法がまずかったようです。
【user.rb】

  def self.from_omniauth(auth)
    sns = SnsCredential.where(provider: auth.provider, uid: auth.uid).first_or_create
    # sns認証したことがあればアソシエーションで取得
    # 無ければemailでユーザー検索して取得orビルド(保存はしない)
    user = sns.user || User.where(email: auth.info.email).first_or_initialize(
      nickname: auth.info.name,
        email: auth.info.email
    )
    # userが登録済みの場合はそのままログインの処理へ行くので、ここでsnsのuser_idを更新しておく
    if user.persisted?
      sns.user = user
      sns.save
    end
    { user: user, sns: sns }
  end

 この記述の中だと、auth(apiから送られてくるユーザーデータ)の中から、:emailを参照してしまいます。
 しかし、私自信、facebookのアカウントにemailを登録していなかったため、この検索に引っかからず、snsの情報をDBに保存していないよねと判断され、弾かれていたようです。
 その後、Facebookのアカウント設定でemailを登録したところ、無事にログインできるようになりました。

今後の課題

このままだと、emailをもたないfacebookユーザーは原因がわからないまま永遠にログインできない状態になってしまいます。ですので、データ参照の仕様を工夫する必要がありそうです、、、