環境
- Ruby v2.5.0
- rails v5.2.0
- omniauth v1.8.1
- omniauth-twitter v1.4.0
雑に試しただけなので色々と変なところあるので注意。
Twitter APP を作成
key | value |
---|---|
Website | http://127.0.0.1:5000 |
Callback URLs | http://127.0.0.1:5000/auth/twitter/callback |
開発環境の場合は localhost
ではエラーになるので 127.0.0.1
を使用する。
ポートは rails が動いているポートに適宜変更すること。
この後使用するので
- Consumer Key (API Key)
- Consumer Secret (API Secret)
は控えておく。
config/secrets.yml に API 情報を記述
twitter_app: &twitter_app
consumer_key: xxxxx
consumer_secret: xxxx
development:
secret_key_base: xxxxx
twitter_app:
<<: *twitter_app
test:
secret_key_base: xxxxx
twitter_app:
<<: *twitter_app
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
twitter_app:
consumer_key: <%= ENV["TWITTER_CONSUMER_KEY"] %>
consumer_secret: <%= ENV["TWITTER_CONSUMER_SECRET"] %>
secret_key_base は以下のコマンドで生成できる。
$ bundle exec rake secret
※ config/secrets.yml は rails 起動中だと反映されないので、起動している場合は再起動する。
Gemfile
最新版を確認して Gemfile に追記
gem 'omniauth', '~> 1.8.1'
gem 'omniauth-twitter', '~> 1.4.0'
インストール
$ bundle install
config/initializers/omniauth.rb を作成
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter,
Rails.application.secrets.twitter_app[:consumer_key],
Rails.application.secrets.twitter_app[:consumer_secret]
end
Rails.application.secrets
は secrets.yml
の値を取得できる。
本当は Rails.application.secrets.twitter_app.consumer_key みたいに取りたかったけどエラーになった。
Model を作成
$ bundle exec rails generate model user provider:string uid:string nickname:string image_url:string
$ bundle exec rake db:migrate
app/models/user.rb を編集
class User < ApplicationRecord
def self.find_or_create_from_auth_hash(auth_hash)
provider = auth_hash[:provider]
uid = auth_hash[:uid]
nickname = auth_hash[:info][:nickname]
image_url = auth_hash[:info][:image]
User.find_or_create_by(provider: provider, uid: uid) do |user|
user.nickname = nickname
user.image_url = image_url
end
end
end
https://github.com/arunagw/omniauth-twitter#authentication-hash
で認証のレスポンスの形式が見れるので必要に応じてカラムを増やすと良い。
Controller を作成
$ bundle exec rails generate controller sessions
app/controllers/sessions_controller.rb を編集
class SessionsController < ApplicationController
def index
end
def create
@user = User.find_or_create_from_auth_hash(request.env['omniauth.auth'])
session[:user_id] = @user.id
redirect_to root_path
end
end
view にファイルを追加
app/views/sessions/index.html.erb
<h1>Sessions#index</h1>
<p>Find me in app/views/sessions/index.html.erb</p>
<%= link_to 'Twitterログイン', '/auth/twitter' %>
<% if session[:user_id] %>
<p>ログイン済み</p>
<% else %>
<p>未ログイン</p>
<% end %>
config/routes.rb に認証コールバック用の URL を追加
root to: 'sessions#index'
get '/auth/:provider/callback', to: 'sessions#create'
omniauth が /auth/:provider
にアクセスした時に各認証画面に遷移してくれるので、コールバックだけ用意すれば良い。
動作確認
起動
$ bundle exec rails server
ブラウザでアクセス 127.0.0.1:5000 にアクセスしてリンクをクリックしてみる。 (ポートは適宜変更)
トラブルシューティング
403 Forbidden が出る
- Twitter APP で設定した URL と異なる URL から認証しようとすると起きる
(うっかり localhost でアクセスしていたら出た。127.0.0.1
でアクセスする。) - Twitter APP 側のコールバックURL と omniauth でのコールバックURLの設定が違う