Mt.Log

編入、編入後の勉強

RailsでDeviseと用いてTwitter認証してみる

はじめに

Railsでブログをつくっているのですが、コメント欄とTwitterを連携させたら面白そうと思いたちTwitter認証をやってみることにしました。
Twitter認証については多くの記事がありますので、詳しくはそちらを参考にしてください。
この記事は半ば自分へのメモ用です。。。
ぼくが参考にさせていただいた記事はこの記事の一番下にまとめてあります。

Twitter Developerへの登録

まず認証に必要なAPIキーを取得するためにTwitter Developer Platformに登録します。
Twitter Developer Platform — Twitter Developers
以前は下のApplication Managementにて登録する流れでしたが、現在Developerに登録する必要があります。
apps.twitter.com
アプリを追加後注意するべきは以下です。

おそらくほかの項目は適当でも大丈夫です。
登録が終わると、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に戻る...はずです。
お疲れ様でした!!!

次回予告

よし、次はこれを使ってツイートしたい!
というわけでやります。やりました。

mtryo1021.hatenablog.com



参考サイト

qiita.com
freesworder.net
freesworder.net