RailsでTwitterログインしてつぶやいてみる
タイトルのことをやってみたくて調べたり作ったりしたので書きます
ログイン編
導入
omniauth-twitter というgemを使いました
omniauthとはなんぞやというと
OmniAuth is a library that standardizes multi-provider authentication for web applications.
webアプリケーションで様々なプロバイダ(twitterとかgithubとか)を使って認証するライブラリです。みたいな感じだと思います
準備のためにGemfile、configに設定を記述します。"API_KEY", "API_SECRET"
は https://apps.twitter.com/ から取得できる値に置き換える必要があります。 値を取得する際に、登録フォームにアプリケーション情報を入力します。項目の1つに「Callback URL」という任意の入力フォームがあるのですが、これにもなんらかの値を入力してやらないと認証チェックの時に弾かれてしまうようです。また、"API_KEY", "API_SECRET"
は多分他人から見られるとよろしくないので、 dotenv など使ってgit管理下から外してやったほうが良いと思います。
# Gemfile gem 'omniauth-twitter' # config/initializers/omniauth.rb Rails.application.config.middleware.use OmniAuth::Builder do provider :twitter, "API_KEY", "API_SECRET" end
ユーザ認証
/auth/twitter
にリダイレクトさせてやると、omniauthが認証に必要な作業を行ってくれるようです。認証の処理が終わった後/auth/:provider/callback
宛に認証情報を持ったhashを渡します(という認識で合っているのかな?)。routes.rbの記述により、認証のコールバックがSessionControllerのcreateアクションに割り当てられます。認証が成功したらブラウザ上に情報が表示されると思います。
# 任意のview = link_to "Sign in with Twitter", "/auth/twitter" # config/routes.rb get '/auth/:provider/callback', to: 'sessions#create' # app/controllers/sessions_controller.rb class SessionsController < ApplicationController def create render text: request.env['omniauth.auth'] end end
それでは、実際に取得した情報をUserとして登録してみます。ネットで見つけた情報をなぞっただけなので適切な方法かは分からないのですが、認証後得られたhash値を見て:provider
、:uid
が既存のUserと一致する場合はそのユーザでログインして、一致しない時はhash値を元にユーザを作成してログインします。最低限:provider
と:uid
だけ保存しておけばログインできると思いますが、今回は画面上にユーザ名と画像を表示したかったので[:info][:name]
と[:info][:image]
を、またアプリ上からつぶやきたかったため、それに必要となるauth[:credentials][:token]
とauth[:credentials][:secret]
の情報も保存しました。これでユーザ登録とログイン機能が実装できました。
# app/controllers/sessions_controller.rb class SessionsController < ApplicationController def create user = User.find_by(provider: auth[:provider], uid: auth[:uid]) || User.create_from_auth!(auth) session[:user_id] = user.id redirect_to '/', notice: 'sign in!' end private def auth request.env['omniauth.auth'] end end
# app/models/user.rb class User < ActiveRecord::Base def self.create_from_auth!(auth) create! do |user| user.provider = auth[:provider] user.uid = auth[:uid] user.name = auth[:info][:name] user.image = auth[:info][:image] user.token = auth[:credentials][:token] user.secret = auth[:credentials][:secret] end end end
次回は「アプリ上からつぶやく編」を書くかもしれません