###実現したいこと
Twitter APIを使用したログイン機能を実装したい。
callbackが通って欲しい。
###ここに質問の内容を詳しく書いてください。
gem 'omniauth-twitter'を使用(deviseは使用してません)して、Ruby on railsでWebアプリを開発しています。
また、許可を求める画面には遷移するのですが、callbackをする際に以下のエラーが出てしまいます。
NoMethodError (undefined method `id' for "1085900685269299200-twitter@example.com":String):app/controllers/sessions_controller.rb:10:in `create'
発生している問題・エラーメッセージ
herokulogs
12020-01-10T15:38:55.521220+00:00 app[web.1]: I, [2020-01-10T15:38:55.521099 #4] INFO -- : [2a9a85d8-ba86-4690-8f80-fd5b68e321ea] Processing by SessionsController#create as HTML 22020-01-10T15:38:55.521806+00:00 app[web.1]: I, [2020-01-10T15:38:55.521733 #4] INFO -- : [2a9a85d8-ba86-4690-8f80-fd5b68e321ea] Parameters: {"oauth_token"=>"h6Zl4wAAAAABBrtcAAABb5AbrwY", "oauth_verifier"=>"qs7ctVofKAniNYibNMfXeZW4VYDDxn86", "provider"=>"twitter"} 32020-01-10T15:38:55.525388+00:00 app[web.1]: I, [2020-01-10T15:38:55.525301 #4] INFO -- : [2a9a85d8-ba86-4690-8f80-fd5b68e321ea] Completed 500 Internal Server Error in 3ms (ActiveRecord: 0.0ms) 42020-01-10T15:38:55.526243+00:00 app[web.1]: F, [2020-01-10T15:38:55.526174 #4] FATAL -- : [2a9a85d8-ba86-4690-8f80-fd5b68e321ea] 52020-01-10T15:38:55.526392+00:00 app[web.1]: F, [2020-01-10T15:38:55.526317 #4] FATAL -- : [2a9a85d8-ba86-4690-8f80-fd5b68e321ea] NoMethodError (undefined method `id' for "1085900685269299200-twitter@example.com":String): 62020-01-10T15:38:55.526526+00:00 app[web.1]: F, [2020-01-10T15:38:55.526460 #4] FATAL -- : [2a9a85d8-ba86-4690-8f80-fd5b68e321ea] 72020-01-10T15:38:55.526666+00:00 app[web.1]: F, [2020-01-10T15:38:55.526572 #4] FATAL -- : [2a9a85d8-ba86-4690-8f80-fd5b68e321ea] app/controllers/sessions_controller.rb:10:in `create'
該当のソースコード
app/models/user.rb↓
usermodel
1class User < ApplicationRecord 2 validates :name, presence: true, length: { maximum: 50 }, unless: :uid? 3 validates :email, presence: true, length: { maximum: 255 }, 4 format: { with: /\A[\w+\-.]+@[a-z\d\-.]+.[a-z]+\z/i }, 5 uniqueness: { case_sensitive: false },unless: :uid? 6 7 has_secure_password nalidations: false 8 validates :password, presence: true, unless: :uid? 9 10 has_many :posts 11 12 def self.find_or_create_from_auth(auth) 13 provider = auth[:provider] 14 uid = auth[:uid] 15 name = auth[:info][:name] 16 email = User.dummy_email(auth) 17 18 # self.find_or_create_by(provider: provider, uid: uid) do |user| 19 # user.username = name 20 # end 21 end 22 23 def self.dummy_email(auth) 24 "#{auth.uid}-#{auth.provider}@example.com" 25 end 26end 27
sessions_controller.rb↓
sessionscontroller
1class SessionsController < ApplicationController 2 def new 3 end 4 5 def create 6 #omniauthを使ったログイン処理 7 auth = request.env['omniauth.auth'] 8 if auth.present? 9 user = User.find_or_create_from_auth(request.env['omniauth.auth']) 10 session[:user_id] = user.id 11 redirect_back_or user 12 else 13 #既存のログイン処理 14 #フォームデータのemailを小文字かして取得(downcase) 15 email = params[:session][:email].downcase 16 #フォームデータのpasswordを取得している 17 password = params[:session][:password] 18 #ログインが成功した時と失敗したときの分岐 19 if login(email, password) 20 flash[:success] = 'ログインに成功しました。' 21 redirect_to @user 22 else 23 flash.now[:danger] = 'ログインに失敗しました。' 24 render :new 25 end 26 end 27 end 28 29 def destroy 30 session[:user_id] = nil 31 flash[:success] = 'ログアウトしました。' 32 redirect_to root_url 33 end 34 35 private 36 37 def login(email, password) 38 #入力フォームで入力されたemailと持つuserを検索し、インスタンス変数に代入 39 @user = User.find_by(email: email) 40 #見つかる時と見つからない時で分岐させ、authenticateで@userのパスワードと合ってるか確認 41 if @user && @user.authenticate(password) 42 # ログインが成功した時(確認して正しい時) 43 session[:user_id] = @user.id 44 return true 45 else 46 # ログインに失敗した時(確認して正しくない時) 47 return false 48 end 49 end 50end 51
routes.rb
routes
1Rails.application.routes.draw do 2 root to: 'toppages#index' 3 4 get 'auth/:provider/callback', to: 'sessions#create' 5 6 get 'login', to: 'sessions#new' 7 post 'login', to: 'sessions#create' 8 delete 'logout', to: 'sessions#destroy' 9 10 get 'signup', to: 'users#new' 11 resources :users, only: %i(index show new create) 12 13 resources :posts, only: %i(create destroy) 14 15 # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html 16end
ルーティング
root_path GET / toppages#index GET /auth/:provider/callback(.:format) sessions#create login_path GET /login(.:format) sessions#new POST /login(.:format) sessions#create logout_path DELETE /logout(.:format) sessions#destroy signup_path GET /signup(.:format) users#new users_path GET /users(.:format) users#index POST /users(.:format) users#create new_user_path GET /users/new(.:format) users#new user_path GET /users/:id(.:format) users#show posts_path POST /posts(.:format) posts#create post_path DELETE /posts/:id(.:format) posts#destroy rails_service_blob_path GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show rails_blob_representation_path GET /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format)active_storage/representations#show rails_disk_service_path GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show update_rails_disk_service_path PUT /rails/active_storage/disk/:encoded_token(.:format) active_storage/disk#update rails_direct_uploads_path POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create
試したこと
herokuに環境変数を通し、emailがnillだと思いdummy_emailを作成する処理をuserモデルに追記しました。
しかし、変わらずにエラーが出てしまいます。
補足情報(FW/ツールのバージョンなど)
Ruby on rails
docker
macos Catalina 10.15.2
herokuでデプロイしています。
独学で勉強中の身のため、理解していないところが多々あるかもしれません。よろしくお願いします。
##参考サイト
[Rails]SNSアカウントログイン機能の実装かつ既存userモデルと衝突しない方法
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/01/11 15:02