🍎

【Ruby on Rails】【不具合解消】SorceryのサブモジュールExternalを使用して、GitHub認証を実装する

2024/07/27に公開

はじめに

こちらの記事にて、SorceryのサブモジュールExternalを使用してGitHub認証を実装した記事を投稿しました。
記事にもある通り、本番環境でログインできないという事象が発生しておりました。
今回はどこに原因があったのか、その内容の記事になります。

なぜ本番環境でログインできなかったのか

結論、実装自体には全く問題はありませんでした。
原因は本番環境で既にGitHubと同一のメールアドレスを使用し、アカウント登録済みであったためでした...。

user.rbで validates :email, uniqueness: true, presence: trueを設定しているため、既に登録済みであったら弾かれるのは当たり前でした。
とてもしょうもない原因でしたが、不具合解消するために色々試したため、その内容を今回の記事にまとめます。

なぜすぐに気がつけなかったのか

  • ローカル環境と本番環境で登録しているアドレスが異なっていたため。
    -> ローカル環境では、GitHubアカウントのメールアドレスを使用していなかったためログインできていました。
    仮にローカル環境でもGitHubアカウントのメールアドレスを使用していたら、ローカル環境でもログインできていなかったはずなので、もう少し早く特定できていたかもしれません...。

  • 本番のサーバーログ上でも、なにもエラーが出ていなかったため
    -> エラーが出ていなかったため、特定に時間がかかった。

不具合解消のために試したこと

今回の不具合解消のために、下記を試しました。

  • ローカル環境と本番環境のログを見比べる。
  • 本番環境上(Render.com)で、環境変数が設定できているかをコンソールで確認。
  • 検証ツールのネットワークタブの確認。
  • SorceryでGitHub認証を行っている方のリポジトリを確認。
  • app/controllers/oauths_controller.rb内で、パラメーターが渡っているか確認するためにputs params[:provider]を随所に配置し、本番環境でもパラメーターが送られている確認。

上記それぞれ記載していきます。


ローカル環境と本番環境のログを見比べる。
下記がローカル環境で、GitHubログインできた時のログになります。
OauthsControllerのcallbackアクションが問題なく処理されていることがわかります。
本番環境ではここでログインできず、トップページにリダイレクトされていました。

エラーが出ていない以上、見比べても解決の糸口は見つけられませんでした。改めて、エラーが出ていることで、解決の糸口に繋がると感じた瞬間でした。

Started GET "/oauth/callback?provider=github&code=c8ac183f2d9bbb9e9ad6" for 192.168.65.1 at 2024-07-19 22:07:05 +0900
web-1  | 22:07:05 web.1  | Cannot render console from 192.168.65.1! Allowed networks: 127.0.0.0/127.255.255.255, ::1
web-1  | 22:07:05 web.1  | Processing by OauthsController#callback as HTML
web-1  | 22:07:05 web.1  |   Parameters: {"provider"=>"github", "code"=>"c8ac183f2d9bbb9e9ad6"}
web-1  | 22:07:06 web.1  |   Authentication Load (1.5ms)  SELECT "authentications".* FROM "authentications" WHERE "authentications"."uid" = $1 AND "authentications"."provider" = $2 ORDER BY "authentications"."id" ASC LIMIT $3  [["uid", "153190696"], ["provider", "github"], ["LIMIT", 1]]
web-1  | 22:07:06 web.1  |   ↳ app/controllers/oauths_controller.rb:11:in `callback'
web-1  | 22:07:06 web.1  |   User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 4], ["LIMIT", 1]]
web-1  | 22:07:06 web.1  |   ↳ app/controllers/oauths_controller.rb:11:in `callback'
web-1  | 22:07:06 web.1  | Redirected to http://localhost:3000/
web-1  | 22:07:06 web.1  | Completed 302 Found in 1531ms (ActiveRecord: 1.9ms | Allocations: 6233)

本番環境上で、環境変数が設定できているかをコンソールで確認。
本番環境でのみログインできなかったため、本番環境で環境変数がうまく設定できていない可能性を疑いました。
今回Render.comに課金をしデプロイしているため、こちらの記事を参考に、コンソールで確認を行いました。

確認方法は上記の記事にとても丁寧に書かれているため、詳細は省略させていただきます。
これまでRender.com上でコンソールを使用したことがなかったので、使用するいい機会となりました。
ただ、本番環境でもきちんと環境変数は設定されていたので、こちらも解決の糸口には繋がりませんでした...。


検証ツールのネットワークタブの確認。
個人記事等を確認したところ、CORSエラーの可能性があるとのことで検証ツールで確認しました。
すると、確かにCORSエラーが出ていました。
Image from Gyazo

ただこちらのCORSエラーは、バックエンドでAPIを立てている場合に起きるらしく(参照)、私の不具合とは無関係でした。
GitHub認証を行っている方のアプリも検証ツールで確認したところ、CORSエラーが出ていたため直接関係はないと判断しました。
そのため、本番環境でログインできた現在もCORSエラーは発生しています。
このままで問題ないのかは、また確認したいと思います。


app/controllers/oauths_controller.rb内で、パラメーターが渡っているか確認するためにputs params[:provider]を随所に起き、本番環境でもパラメーターが送られている確認

app/controllers/oauths_controller.rbでパラメーターを使用してGitHub情報を取得しているため、このパラメーターが本番環境でうまく渡っていない可能性を考えました。
そこで、各所にputs params[:provider]を置き、きちんとパラメーターが本番環境でも問題なく渡っているかを確認しました。
こちらも問題なく、完全に行き詰まってました...。

class OauthsController < ApplicationController
  skip_before_action :require_login, raise: false

  def oauth
    login_at(params[:provider])
  end

  def callback
    provider = params[:provider]
    if @user = login_from(provider)
      redirect_to articles_path, notice: "#{provider.titleize}アカウントでログインしました。"
    else
      begin
        @user = create_from(provider)
        reset_session
        auto_login(@user)
        redirect_to articles_path, notice: "#{provider.titleize}アカウントでログインしました。"
      rescue
        redirect_to root_path, :notice => "#{provider.titleize}アカウントでログインに失敗しました。"
      end
    end
  end
end

どのように気がついたのか

今回上記の通り、一通り確認作業を行って解決の糸口が見つけられなかったので、別issueへ取り組んでいました。(上記の確認作業で2日半は使用したと思います...)
また、GitHub認証をSorceryのサブモジュールExternalを使用して書いている記事がほとんどなく、LINE認証、Google認証の記事も確認しました。

余談ですが、SorceryのサブモジュールExternalを使用した場合、どの外部認証でも基本的には実装方法は同じだったので、その点のできて良かったと思います。

ただ他記事を拝見しても解決はできなかったため、5日程度日をを置いて別issueに取り組んでいました。

そして今日、再度この問題解決に取り組んでいる際に、「そういえばGitHubアカウントと通常ログインで同じメールアドレスを使ってるよな...」と思い出し、解消に至りました。

もう少し早く気づければとも思いましたが、なぜ本番環境でのみログインできないのか、いろんな角度から考えることができ良かったです。
学習を始めた当初は、ChatGPTに確認しハルシネーションに悩まされることが多々ありましたが、現在ではどう解決すべきか自分なりに調べて確認することができるようになりました。

今後もエラーに遭遇した際には、どこに原因があるのか仮説を立てながら確認作業を行なっていきたいと思います。
ありがとうございました。

参照

Discussion