Rails5でOmniAuthを使ったTwitter連携(認証編)
Rails5.1.5でOmniAuthを使ったTwitter連携機能を実装してみます。
今回の記事は参考記事の追試の側面が大きいので、参考記事を見たほうが速いかもしれません。
目標
以下のようなアプリの制作を目標とします。
- / → アカウント情報表示、未ログインで/loginに遷移
- /auth/twitter → Twitter認証実行
- /auth/twitter/callback → Twitter認証後のコールバック先
- /logout → ログアウト処理
- /login → ログインを促す画面表示
準備
こちらで[Create New App]ボタンを押し、新規にツイッターアプリを作ってください。Name~Websiteの項目は好きに埋めてください。Callback URLのみ、
<アプリのURL>/auth/twitter/callback
としてください。後ほどこのURLをコールバック先としてアプリを作ります。
アプリを作ったらAPIキーを控えます。APIキーはKeys and Access Tokensタブ内のApplication Settings欄に表示されています。~/.bashrcや~/.bash_profile等の設定ファイルに以下を追記し、環境変数にAPIキーを保存します。
export TWITTER_API_KEY=<API_KEY>
export TWITTER_API_SECRET=<API_SECRET>
OmniAuthの導入
gemfileに以下を追記します。
gemfile
gem 'omniauth'
gem 'omniauth-twitter'
追記後、bundle installを実行します。
config/secrets.ymlにAPIキーを追記します。
config/secrets.yml
twitter: &twitter
twitter_api_key: <%= ENV["TWITTER_API_KEY"] %>
twitter_api_secret: <%= ENV["TWITTER_API_SECRET"] %>
development:
secret_key_base: <hogehoge>
<<: *twitter
test:
secret_key_base: <fugafuga>
<<: *twitter
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
<<: *twitter
config/initializers/omniauth.rbにconfig/secrets.ymlを利用した設定を追記します。
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter,Rails.application.secrets.twitter_api_key,Rails.application.secrets.twitter_api_secret
end
ルーティング
以下のようにルーティングを行います。
config/routes.rb
root :to => 'home#index'
get '/auth/twitter/callback', to: 'sessions#create'
get '/logout', to: 'sessions#destroy'
get '/login', to: 'home#login'
モデルの制作
認証後に得られるユーザーの情報を格納するuserモデルを制作します。
rails generate model User provider:string uid:string nickname:string name:string image_url:string description:string
rails db:migrate
できたモデルに、認証後にデータの検索及び生成を実行するメソッドを追加します。
models/user.rb
class User < ApplicationRecord
def self.find_or_create_from_auth(auth)
provider = auth[:provider]
uid = auth[:uid]
nickname = auth[:info][:nickname]
name = auth[:info][:name]
image_url = auth[:info][:image]
description = auth[:info][:description]
self.find_or_create_by(provider: provider, uid: uid) do |user|
user.nickname = nickname
user.name = name
user.image_url = image_url
user.description = description
end
end
コントローラの制作
セッションを管理するSessionsと、ログイン画面及びアカウント情報を表示するHomeの二つのコントローラーを制作します。
rails generate controller Sessions create destroy
rails generate controller Home index login
sessions_controller.rbの中身を書いていきます。コールバック先のリクエスト内容に含まれる認証情報をuserモデルのfind_or_create_from_auth()に渡し、生成及び取得を行い、セッションにidを格納するcreateメソッドとreset_sessionを行い、セッション内容を破棄することでログアウトを行うdestroyメソッドを作成します。
sessions_controller.rb
class SessionsController < ApplicationController
def create
user = User.find_or_create_from_auth(request.env['omniauth.auth'])
session[:user_id] = user.id
redirect_to root_path
end
def destroy
reset_session
redirect_to root_path
end
end
home_controller.rbの中身を書いていきます。session内のuser_idの存在を確認し、nilならば未ログインと見做し、login画面に遷移します。存在していれば、@user内に対象ユーザーのデータを格納します。
home_controller.rb
class HomeController < ApplicationController
def index
if session[:user_id].nil?
redirect_to action:'login'
else
@user = User.find(session[:user_id])
end
end
def login
end
end
ビューの制作
ユーザー情報を表示するビューを制作します。@user内にユーザー情報を格納してあるので、これらを全て表示し、さらにログアウト用のリンクも追加します。
home/index.html.erb
<p><%= "name:" + @user[:nickname]%></p>
<p><%= "screen_name:" + @user[:name]%></p>
<p><%= "image_url:" + @user[:image_url]%></p>
<p><%= "description:" + @user[:description]%></p>
<%= link_to "logout" ,:controller => "sessions", :action => "destroy" %>
ログインを促すビューを制作します。といっても、認証を行う/auth/twitterに遷移するリンクを表示するだけです。
home/login.html.erb
<%= link_to "login" ,"/auth/twitter" %>