Help us understand the problem. What is going on with this article?

[学習用]Rails5+herokuで Twitter認証を実装する:deviseを使ってない場合

More than 1 year has passed since last update.

Twitterauthapp (1).jpg
Twitterauthapp (2).jpg

Twitterauthapp.jpg

くじけそうになったが何とか認証まで成功したのでメモ

結論

いろんなサイトのコードをマネして何度も失敗しましたが、ソースコードが間違っているのではなくcallbackの記述が間違っているかと思われます。
成功した流れとコードをメモしておきます。
※ローカルでもHerokuでも動作確認できました。
 callbackにローカルアドレス入れたら出来ました。

環境

Rails 5.2.1
Ruby  2.5.1
heroku

ubuntu16
IntelliJ IDEA

重要:困ったら

API keysを作成と確認

Twitter Developers.jpg

Twitter から Consumer API keys を作成する

  • API key
  • API secret key

これが無いと作れません。
キーを間違わない様にコピペしておきましょう。
Consumer API keysの方で良いです。

苦戦する Callback URL の確認

Twitter   アプリケーション認証.jpg

Callback URL は色々なところで書かれているが、
APIの仕様が結構変わるらしく最新の記述方法じゃないとエラーで弾かれます。

結局 2018/11/30 時点で成功した方法は

https://ドメイン名 + auth/twitter/callback が正解でした。

Heroku例:https:// ドメイン名.herokuapp.com/auth/twitter/callback
ローカル例:http:// 192.168.xx.yy:3000/auth/twitter/callback

Twitter Developers (1).jpg

たぶんどこのサイトの例やサンプルコードをマネしてもエラーが出るのはこの記述が違うから弾かれるんだと思います。

アプリ作成:ここからはじまり

$ rails new twitterauthapp -d postgresql
$ cd twitterauthapp
$ bundle

gem の追加

gem 'omniauth'
gem 'omniauth-twitter'

env ファイルを作成

/.env
APP_ID = "API key を入れます"
APP_SECRET = "API secret key を入れます"

空ファイルを作成して上記の内容を記載します。
Twitter から Consumer API keys コピペースとします。

env を公開しない設定

/.gitignore
/.env

.gitignore へ 上記を追加することでConsumer API keysがアップロードされなくなります。

omniauth.rb を作成

/config/initializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :twitter, ENV['APP_ID'], ENV['APP_SECRET']
end

ファイルを新しく手動で作成します。
空ファイル作成してコピペでOK。

user モデルを作成

$ rails g model user provider:string uid:string user_name:string image_url:string

devise を使ってないバージョンです。
既に使っている場合は書き方が違いました。

作成した user モデルに記述

/app/models/user.rb
class User < ApplicationRecord
  def self.find_or_create_from_auth(auth)
    provider = auth[:provider]
    uid = auth[:uid]
    user_name = auth[:info][:user_name]
    image_url = auth[:info][:image]

    self.find_or_create_by(provider: provider, uid: uid) do |user|
      user.user_name = user_name
      user.image_url = image_url
    end
  end
end

新規登録用のコントローラーを作成

$ rails g controller sessions
/app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
  def create
    user = User.find_or_create_from_auth(request.env['omniauth.auth'])
    session[:user_id] = user.id
    flash[:notice] = "ユーザー認証が完了しました。"
    redirect_to root_path
  end

  def destroy
    reset_session
    flash[:notice] = "ログアウトしました。"
    redirect_to root_path
  end
end

ヘルパーメソッドを追加

/app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  helper_method :current_user, :logged_in?

  private

  def current_user
    return unless session[:user_id]
    @current_user ||= User.find(session[:user_id])
  end

  def logged_in?
    !!session[:user_id]
  end

  def authenticate
    return if logged_in?
    redirect_to root_path, alert: "ログインしてください"
  end
end

ログイン画面を作成

$ rails g controller home index

とりあえず、ログイン出来るリンクを追加するので作成します。

Twiiterログインリンクを作成

/app/views/home/index.html.erb
<% if session[:user_id]==nil %>
  <%= link_to "Twitterログイン", "/auth/twitter"%>
<% else %>
  <%= link_to "Twitterログアウト", "/logout"%>
<% end %>

ログイン用のリンク。

ルーティングを設定する

/config/routes.rb
Rails.application.routes.draw do
  get 'home/index'
  get '/auth/:provider/callback', to: 'sessions#create'
  get '/logout', to: 'sessions#destroy'
  root 'home#index'
end

ログイン用のリンクをTOPにしておきます。

ローカルで画面の確認

$ rails db:create
$ rails db:migrate

TOP画面は問題無く出せました。
ローカル環境でも動作確認できました。

ここでローカルが動作しないのであれば、
ローカル用の Callback URL が適切でないかなと思います。

※rails db:create はしなくても良いと思いますが、自分の環境では何度も書いて消したので
 データベースが残ってたか作成されてなかったので作成しました。

Herokuへデプロイ

$ heroku create twitterauthapp 
$ git init
$ git add .
$ git commit -am "test auth"
$ git push heroku master
$ heroku run rails db:migrate

$ heroku config:set APP_ID=API key を入れます
$ heroku config:set APP_SECRET=API secret key を入れます

Herokuに API key、API secret key を登録します。

$ heroku config

API key、API secret keyが登録されているか確認できます。

アプリURLを決めてから毎度おなじみコマンドです。
HerokuへAPI key、API secret key とdb:migrateを忘れずに。

認証成功した画面

Twitter   設定.jpg

これでアップした画面のURLをクリックするとTwitter認証画面がでます!

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away