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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Devise

Deviseとは、Ruby-on-Railsの認証機能を追加するプラグインです。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Facebook

Facebookは、実名登録制のSNS(ソーシャル・ネットワーキング・サービス)です。開発者用のデベロッパーサイトが存在し、一般ユーザーによるFacebook向けアプリケーション開発が可能です。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

0回答

2102閲覧

Rails6 devise_token_authとomniauthを使用したFacebookやGoogleとのSNS認証を実現したい

lefmarna

総合スコア1

Devise

Deviseとは、Ruby-on-Railsの認証機能を追加するプラグインです。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Facebook

Facebookは、実名登録制のSNS(ソーシャル・ネットワーキング・サービス)です。開発者用のデベロッパーサイトが存在し、一般ユーザーによるFacebook向けアプリケーション開発が可能です。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2021/05/02 06:00

前提・実現したいこと

RailsをAPIモードで運用していて、ログイン認証にはdevise_token_authを使っています。

devise_token_authを使うという前提は変えずに、omniauthを使用したFacebookやGoogleとのSNS認証を実現したいと考えております。

APIモードでないRailsのアプリではdevise_token_authではなく、Deviseを使っていました。そちらでは実現できた機能だったので、APIモードのアプリに落とし込もうと思ったのですがうまくいきませんでした。

発生している問題・エラーメッセージ

期待していたルーティングが表示されません。

Deviseを使っていた非APIモードのアプリでは以下のようなルーティングを確認できていました。

user_facebook_omniauth_authorize GET|POST /users/auth/facebook(.:format) users/omniauth_callbacks#passthru user_facebook_omniauth_callback GET|POST /users/auth/facebook/callback(.:format) users/omniauth_callbacks#facebook user_google_oauth2_omniauth_authorize GET|POST /users/auth/google_oauth2(.:format) users/omniauth_callbacks#passthru user_google_oauth2_omniauth_callback GET|POST /users/auth/google_oauth2/callback(.:format) users/omniauth_callbacks#google_oauth2

一方で、APIモードのアプリ(devise_auth_token)使用時は以下のようなルーティングになっています。

api_v1_auth_failure GET /api/v1/auth/failure(.:format) api/v1/auth/omniauth_callbacks#omniauth_failure GET /api/v1/auth/:provider/callback(.:format) api/v1/auth/omniauth_callbacks#omniauth_success GET|POST /omniauth/:provider/callback(.:format) api/v1/auth/omniauth_callbacks#redirect_callbacks omniauth_failure GET|POST /omniauth/failure(.:format) api/v1/auth/omniauth_callbacks#omniauth_failure GET /api/v1/auth/:provider(.:format) redirect(301)

該当のソースコード

config/routes.rb

ruby

1Rails.application.routes.draw do 2 namespace :api, { format: 'json' } do 3 namespace :v1 do 4 mount_devise_token_auth_for 'User', at: 'auth', controllers: { 5 omniauth_callbacks: 'api/v1/auth/omniauth_callbacks', 6 registrations: 'api/v1/auth/registrations' 7 } 8 resources :users, only: [:index, :show], param: :username 9 end 10 end 11end

app/controllers/application_controller.rb

ruby

1class ApplicationController < ActionController::API 2 include DeviseTokenAuth::Concerns::SetUserByToken 3 4 before_action :configure_permitted_parameters, if: :devise_controller? 5 6 private 7 8 def configure_permitted_parameters 9 devise_parameter_sanitizer.permit(:sign_up, keys: [:username, :nickname]) 10 end 11end

app/controllers/api/v1/auth/omniauth_callbacks_controller.rb

ruby

1class Api::V1::Auth::OmniauthCallbacksController < DeviseTokenAuth::OmniauthCallbacksController 2 3 def facebook 4 authorization 5 end 6 7 def google_oauth2 8 authorization 9 end 10 11 private 12 13 def authorization 14 @user = User.from_omniauth(request.env["omniauth.auth"]) 15 end 16end

app/models/user.rb

ruby

1class User < ActiveRecord::Base 2 devise :database_authenticatable, :registerable, 3 :recoverable, :rememberable, :validatable, :omniauthable, omniauth_providers: [:facebook, :google_oauth2] 4 include DeviseTokenAuth::Concerns::User 5 6 7 with_options presence: true do 8 validates :username, uniqueness: { case_sensitive: false }, length: { minimum: 3, maximum: 25 }, 9 format: { with: /\A[a-z\d]+\z/i } 10 validates :nickname 11 end 12end

Gemfile

ruby

1# ログイン認証 2gem 'devise' 3gem 'devise_token_auth' 4 5# SNS認証 6gem 'omniauth', '~>1.9.1' 7gem 'omniauth-facebook' 8gem 'omniauth-google-oauth2' 9gem 'omniauth-rails_csrf_protection'

試したこと

コントローラー内で

providerにfacebookを入れれば飛べるのかと考え、api/v1/auth/facebook にアクセスしてみました。
すると、以下のようなエラーが表示されました。

OmniAuth::NoSessionError (You must provide a session to use OmniAuth.):

調べてみると、APIモードでは application.rb に特殊な記述が必要ということで、以下の記述をしました。

ruby

1 config.session_store :cookie_store, key: '_interslice_session' 2 config.middleware.use ActionDispatch::Cookies # Required for all session management 3 config.middleware.use ActionDispatch::Session::CookieStore, config.session_options

すると上記のエラーは解消したのですが、続いて以下のようなエラーが発生してしまいました。

ActionController::RoutingError (No route matches [GET] "/omniauth/facebook"):

/omniauth/facebookが見つからないと言われているので、無理やりルーティングとコントローラーを用意してみました。

app/controllers/omniauth_controller.rb

ruby

1class OmniauthController < DeviseTokenAuth::OmniauthCallbacksController 2 def facebook 3 authorization 4 end 5 6 def google_oauth2 7 authorization 8 end 9 10 private 11 12 def authorization 13 @user = User.from_omniauth(request.env["omniauth.auth"]) 14 end 15end

この状態でアクセスしてみると、またもエラーが発生していました。

NoMethodError (undefined method `from_omniauth' for #<Class:0x00007efc549ba760>):

from_omniauthというメソッドはドキュメントのものなので、さすがにお手上げで質問させてもらいました。

APIモードでの開発に関しては初心者でして、devise_token_authについてもあまり詳しくないので、詳細に教えていただけると助かります。

補足情報(FW/ツールのバージョンなど)

ruby:2.6.5
rails:6.0.3

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問