RailsでDeviseと用いてTwitter認証してみる
はじめに
Railsでブログをつくっているのですが、コメント欄とTwitterを連携させたら面白そうと思いたちTwitter認証をやってみることにしました。Twitter認証については多くの記事がありますので、詳しくはそちらを参考にしてください。
この記事は半ば自分へのメモ用です。。。
ぼくが参考にさせていただいた記事はこの記事の一番下にまとめてあります。
Twitter Developerへの登録
まず認証に必要なAPIキーを取得するためにTwitter Developer Platformに登録します。Twitter Developer Platform — Twitter Developers
以前は下のApplication Managementにて登録する流れでしたが、現在Developerに登録する必要があります。
apps.twitter.com
アプリを追加後注意するべきは以下です。
- URIをhttp://127.0.0.1:3000/にする。
- Redirect URIをhttp://127.0.0.1:3000/users/auth/twitter/callbackにする。(のちのDeviseで作成するモデルの名前に依存する。)
- PermissionをRead, Write and Access direct messagesにする。
おそらくほかの項目は適当でも大丈夫です。
登録が終わると、Keys and Access Tokensの欄にConsumer KeyとConsumer Secretがあります。今回は、このキーを使います。
Gemの編集
今回使用するGemを入れます。ログイン処理用にDevise、Twitter認証用にOmniauthを使用します。
Deviseはログイン機能を簡単に実装できるGemです。
dotenvはAPIキーを保持するためのGemです。
gem 'devise' gem 'omniauth' gem 'omniauth-twitter' gem 'dotenv'
Gem fileを編集後installします。
$ bundle install --path vendor/bundle
Deviseの設定
Deviseでのログイン機能を実装していきます。下のコマンドを実行していきます。
$ bundle exec rails g devise:install $ bundle exec rails g devise:views $ bundle exec rails g devise User $ bundle exec rails g migration add_columns_to_users provider uid username $ bundle exec rails db:migrate
これでログイン機能の実装は終わりです。(簡単!!!
はじめの方は実行して試してみましょう!
$ bundle exec rails s
.envにAPIキーを保存
アプリの直下に.envファイルを作成します。$ emacs .env
ここにAPIキーを書いていきます。
TWITTER_CONSUMER_KEY="あなたのAPIキー" TWITTER_CONSUMER_SECRET="あなたのAPIシークレット"
これは、
ENV["TWITTER_CONSUMER_KEY"]
などとすると取り出すことができます。
Consoleなどで試してみるといいでしょう。
Twitter認証の設定
いよいよ本題です。ログイン後に表示するページを作ります。
$ bundle exec rails g controller Pages index show
ルーティングの設定をします。
config/routes.rb
root 'pages#index' get 'pages/show' devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
UserモデルをTwitter用に編集します。
emailはダミーを登録しないとエラーになるそうです。
models/user.rb
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :omniauthable def self.find_for_oauth(auth) user = User.where(uid: auth.uid, provider: auth.provider).first unless user user = User.create( uid: auth.uid, provider: auth.provider, email: User.dummy_email(auth), username: auth.info.nickname, password: Devise.friendly_token[0, 20] ) end user end private def self.dummy_email(auth) "#{auth.uid}-#{auth.provider}@example.com" end
表示するViewを編集します。
views/layouts/application.html.erb
<header> <nav> <% if user_signed_in? %> <strong><%= link_to current_user.username, pages_show_path %></strong> <%= link_to 'プロフィール変更', edit_user_registration_path %> <%= link_to 'ログアウト', destroy_user_session_path, method: :delete %> <% else %> <%= link_to 'サインアップ', new_user_registration_path %> <%= link_to 'ログイン', new_user_session_path %> <% end %> </nav> </header> <p class="notice"><%= notice %></p> <p class="alert"><%= alert %></p>
views/pages/index.html.erb
<% if user_signed_in? %> <h1>こんにちは、<%= current_user.username %>さん</h1> <p>ユーザー用ページです。</p> <% else %> <p>ログインしてください</p> <% end %>
ログインしているかの確認
controllers/application_controller.rb
protect_from_forgery with: :exception before_action :authenticate_user!
Deviseのinitializersに次を追加します。
config/initializers/devise.rb
config.omniauth :twitter, ENV["TWITTER_CONSUMER_KEY"], ENV["TWITTER_CONSUMER_SECRET"]
Callback用のControllerを作成し、編集します。
$ bundle exec rails g controller users/omniauth_callbacks
controllers/users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController def twitter callback_from :twitter end private def callback_from(provider) provider = provider.to_s @user = User.find_for_oauth(request.env['omniauth.auth']) if @user.persisted? flash[:notice] = I18n.t('devise.omniauth_callbacks.success', kind: provider.capitalize) sign_in_and_redirect @user, event: :authentication else session["devise.#{provider}_data"] = request.env['omniauth.auth'] redirect_to new_user_registration_url end end end
実行
ここまでで完成です。$ bundle exec rails s
Sign in with twitterにてTwitter認証のサイトにいき認証後rootに戻る...はずです。
お疲れ様でした!!!
次回予告
よし、次はこれを使ってツイートしたい!というわけで
参考サイト
qiita.comfreesworder.net
freesworder.net