今回は、Twitter APIを利用して、deviseのログインでTwitterアカウントでログインできるようにしていきます。
APIを使うことで、かんたんにTwitterと連携ができます。
では、さっそくいきましょう!
#完成イメージ
完成イメージはこちらです
TwitterアカウントでログインをクリックするとTwitterアカウントでログインできます。
動作確認したい方は、ぼくのポートフォリオに実装してますので、確認してみてください。
#開発環境
ruby 2.6.3
Rails 5.2.6
#前提
今回のTwitterでのログインは、deviseを使用しますので、deviseを使ったログイン機能の実装を済ませておいてください。
deviseのかんたん導入手順
さくっとdeviseをつかってみる
#TwitterAPI登録
まずは、TwitterAPIに登録することから始めます。
登録にはTwitterアカウントが必要なので、開発用であれば新規にアカウントを作成するのもアリかもです。
少し古い記事ですが、ぼくはこの記事を参考にしました。
画面キャプチャと実際の画面は少し違いましたが、問題なく登録できたので、問題ないと思います。
Twitter API 登録 (アカウント申請方法) から承認されるまでの手順まとめ
その場ですぐ登録完了ではなく、審査がありますので、先に申請しておくことをおすすめします。
ぼくの場合は申請してから、1日後には承認されました。
####callbackURL
TwitterAPIの画面でcallbackURLを設定できます。
callbackURLに記載のURLのみが、Twitter認証が許可されますので、本番環境URLと開発環境URLを登録しておきましょう。(何個でも登録可能)
・本番環境
https://[ドメインまたはIPアドレス]/users/auth/twitter/callback
・開発環境
https://localhost:3000/users/auth/twitter/callback
・開発環境がcloud9の場合
cloud9でブラウザを開いたURLが入るので、https://のあとからamazonaws.comまで
のURLをコピペ
https://[amazonaws.comまでのURL]/users/auth/twitter/callback
これで、本番環境、開発環境で登録しておけば、どちらの環境でも動作確認ができます。
####API KeyとAPI Secret Key
取得したAPI Key
とAPI Secret Key
はあとで、使うのでメモしておいてください。
#Gemのインストール
Gemは2つのGemをインストールしていきます。
omniauth
というGemは、SNSなどの複数の外部サービスのログインや登録を管理できるGemです。
omniauthは、各SNSごとに別のGemが用意されているので併用して使います。
gem 'omniauth', '1.9.1'
gem 'omniauth-twitter'
ここで注意してほしいのが、omniauthのバージョン
を指定している点です。
現在の最新のバージョンは、2.いくらなのですが、仕様が変更して、最新のバージョンだと今回の方法ではうまく動作しません。
実際このバージョンを指定しなかったため、2日ほど時間を無駄にしました。。。(初心者にバージョン違いのエラーは厳しすぎる...)
$ bundle install
お忘れなく。
#API KeyとAPI Secret Keyを環境変数に
API KeyとAPI Secret Keyは、だれにも知られたくないので、.envファイルに記述して環境変数にしていきます。
####環境変数わからない方向けに、ざっと説明
環境変数にせずにファイルにそのままAPI KeyやAPI Secret Keyを記述して、GitHubにあげてしまうと、全世界に向けて大事な大事な情報を公開してしまいます。
なので、GitHubに大事な情報はあげないように設定をします。
手順としては、以下
- gem 'dotenv-rails'をインストール
- .envファイルを作成しその中に環境変数を定義
- gitignoreファイルに.envを追加
今回は、環境変数を定義するところから解説していきます。
####.envファイルに記述
環境変数として、
API Keyは、TWITTER_CONSUMER_KEY
API Secret Keyは、TWITTER_CONSUMER_SECRET
DOMAIN_NAMEには、動作確認したい環境のドメインまたはIPアドレスを入れてください。
TWITTER_CONSUMER_KEY = "メモしたAPI Key"
TWITTER_CONSUMER_SECRET = "メモしたAPI Secret Key"
DOMAIN_NAME = "ドメインまたはIPアドレス"
まずは開発環境で動作確認して問題なければ、本番環境のドメインまたはIPアドレスを入れるといいと思います。
EC2サーバーを使う場合は、cloud9では開発環境、ES2サーバー上では本番環境のドメインまたはIPアドレスに変更する方法もあります。(こっちのほうが、デプロイ後も開発環境で動作確認できるのでいいかも)
####gitignoreに追加
せっかく.envファイルに環境変数を定義しても、このままだとGitHubにあがってしまうので、gitignoreファイルに.envを追加してGitHubにあげないように設定します。
:
.env
#deviseの設定
deviseで、Twitter認証が行われるように.envファイルに環境変数として定義した値を用いて設定を記述します。
:
# Twitter認証
config.omniauth :twitter, ENV['TWITTER_CONSUMER_KEY'], ENV['TWITTER_CONSUMER_SECRET'], scope: 'email', oauth_callback: "#{ENV['DOMAIN_NAME']}/users/auth/twitter/callback"
OmniAuth.config.logger = Rails.logger if Rails.env.development? # debug用
end
omniauthでtwitterが使えるように設定を追加します。
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable,
# Twitter API認証用に追加
:omniauthable, omniauth_providers: [:twitter]
:
#Twitter認証時にUserモデルでデータを作る
Twitter認証でログインした際に、
はじめてのログインの場合は、Twitterの情報を元に新しくユーザーを登録する。
すでに作成済みの場合は、Userテーブルから同じデータを持ってくる。
という処理を記述していきます。
####Userテーブルにカラムを追加
Twitter認証をしているユーザーかを判断するために、uidカラムとproviderカラムを追加します。
$ rails g migration AddColumnsToUsers uid:string provider:string
$ rails db:migrate
####userモデルに処理を記述
userモデルに、Twitter認証時のログインに関する処理を記述していきます。
# Twitter認証ログイン用
# ユーザーの情報があれば探し、無ければ作成する
def self.find_for_oauth(auth)
user = User.find_by(uid: auth.uid, provider: auth.provider)
user ||= User.create!(
uid: auth.uid,
provider: auth.provider,
name: auth[:info][:name],
email: User.dummy_email(auth),
password: Devise.friendly_token[0, 20]
)
user
end
# ダミーのメールアドレスを作成
def self.dummy_email(auth)
"#{Time.now.strftime('%Y%m%d%H%M%S').to_i}-#{auth.uid}-#{auth.provider}@example.com"
end
userテーブルにemailを保存する必要がある場合は、ダミーのメールアドレスを作成します。
####omniauthコントローラーの設定
コールバック時の処理を記述していきます。
:
# コメントアウト外して、処理追加(8行目あたり)
def twitter
callback_from :twitter
end
:
# 最後のendの直前に記載
private
# コールバック時に行う処理
def callback_from(provider)
provider = provider.to_s
@user = User.find_for_oauth(request.env['omniauth.auth'])
# persisted?でDBに保存済みかどうか判断
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
ルーティング
omniauth_callbacksのルーティングを設定します。
devise_forに追加してください。
devise_for :users, controllers: {
sessions: 'users/sessions',
passwords: 'users/passwords',
registrations: 'users/registrations',
# Twitter API認証用
:omniauth_callbacks => 'users/omniauth_callbacks',
}
#ビュー
最後に、ビューにTwitter認証用のリンクを作成していきます。
今回は、deviseの_links.html.erbファイルに記述していきます。
他にもregistrationやsessionの、newファイルに直接記述する方法もあります。
ご自身のお好きなスタイルにあわせて、カスタマイズしてください。
:
<%- if devise_mapping.omniauthable? %>
<%- resource_class.omniauth_providers.each do |provider| %>
<!--以下1行を編集-->
<%= link_to "#{OmniAuth::Utils.camelize(provider)}アカウントでログイン", omniauth_authorize_path(resource_name, provider), class:'fab fa-twitter', method: :post %>
<% end %>
<% end %>
これで、この作成したリンクをクリックすることで、Twitter認証画面に飛んで、認証できればログインできるようになります!
#まとめ
はじめてAPIを使ったので、苦労しましたが、いい経験になりましたし、ユーザーも新しいアカウントを作る手間がなくなるので、使い勝手も上がりました!
苦労した点としては、
TwitterAPIとdeviseを組み合わせる方法が、deviseの無しの方法より難しかった。
なにより、omniauthのバージョン指定にはやられましたw
今後はTwitter以外のFacebookやGoogleなんかの認証にもチャレンジしていきたいですね!
同じようなところで詰まってる方の参考になれば幸いです。