Ruby on Rails でOmniAuthで認証してつぶやく

自分の環境だと参考にさせてもらったままだとうまく動かなくて色々いじってみた。 過不足あるかもだけどとりあえず動いたのでまとめ。

https://github.com/sagiO/Ruby_on_Rails_Tweet

できたこと

  • OmniAuthで認証
  • ログインしたユーザでツイート
  • githubにpushしてもコンシューマーキーを隠蔽化(figaroで)

参考

認証:

Ruby on Rails で Oauth を使う - d4i.log

そういうことだったんですね

OmniAuthで認証機能を作る - RuntimeError

ツイート:

Ruby: Rails で Twitter アプリ | snippets.feb19.jp

隠蔽化:

便利gem ~figaro~ - 初心者エンジニアのメモ帳

新規アプリ作成。
gem追加。
OmniAuthはOAuth認証、figaroはキー管理、twittertwitterアクセスに使用。

# /Gemfile
gem 'omniauth-twitter'
gem 'figaro'
gem 'twitter'

bundle install。

$ bundle install

Developers Site にアプリを登録

https://dev.twitter.com

Callback URL を下記で設定

http://127.0.0.1:3000/auth/twitter/callback

「Read and Write」と「Signed in Twitter」にチェック API KEY,API SECRET を控えます。

figaro のインストール

$ rails g figaro install

API KEY,API SECRETを設定

# config/application.yml
TWITTER_KEY: (控えてたAPI KEY)
TWITTER_SECRET:(控えてたAPI SECRET)

OmniAuth 用のイニシャライザーを用意

# config/initializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET']
    Twitter.configure do |config|
        config.consumer_key = ENV["TWITTER_KEY"]
        config.consumer_secret = ENV["TWITTER_SECRET"]
    end
end

ルートの定義
(ここで、signoutのメソッドがうまくdeleteでは指定できなかった。。なんでだろ??)

# config/routes.rb
  resources :sessions, only: [:create]
  resources :messages, only: [:index, :create]

  root 'sessions#index'

  match '/auth/:provider/callback', to: 'sessions#create', via: 'get'
  match '/signout', to: 'sessions#destroy', via: 'post'

コントローラの作成

$ rails g controller sessions create destroy
$ rails g controller messages create
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base

  helper_method :current_user

    def current_user
      @current_user ||= User.find(session[:user_id]) if session[:user_id]
    end
end
# app/controllers/sessions_controller.rb
class SessionsController < ApplicationController

  def create
    auth = request.env["omniauth.auth"]
    user = User.find_by_provider_and_uid(auth["provider"], auth["uid"]) || User.create_with_omniauth(auth)
    session[:user_id] = user.id
    session[:oauth_token] = auth["credentials"]["token"]
    session[:oauth_token_secret] = auth["credentials"]["secret"]
    redirect_to root_url, notice => "Siged in!"
  end

  def destroy
    session[:user_id] = nil
    session[:oauth_token] = nil
    session[:oauth_token_secret] = nil
    redirect_to root_url, notice => "Signed out!"
  end
end
# app/controllers/messeges_controller.rb
class MessagesController < ApplicationController

  def create
    twitter_client = Twitter::Client.new.configure do |config|
        config.oauth_token = session[:oauth_token]
        config.oauth_token_secret = session[:oauth_token_secret] 
        end
    twitter_client.update(params[:message])
    redirect_to messages_path
  end
end

モデルの作成

$ rails g model user
$ rake db:migrate
# app/models/user.rb
class User < ActiveRecord::Base
  def self.create_with_omniauth(auth)
    create! do |user|
      user.provider = auth["provider"]
      user.uid = auth["uid"]
      user.name = auth["info"]["name"]
    end
  end
end

ビューの作成

# app/views/sessions/index.html
<% if current_user %>
  Welcome <%= current_user.name %>
  <lu>
    <li><%= link_to "ツイート", messages_path %></li> 
      <li><%= link_to "サインアウト", '/signout', method: :destroy %></li> 
     </lu>
<% else %>
  <%= link_to "サインイン with Twitter", "/auth/twitter" %> 
<% end %>
# app/views/messages/index.html
<%= form_tag({action: 'create'}, {method: 'post'}) do %>
    <%= text_field_tag(:message) %>
    <%= submit_tag(:submit) %>
<% end %>

1時間で作るっていうのを見て食いついちゃったんだけど、ズブの素人にはかなり時間かかった。 でも、デバッガとか入れて調査を進める過程を体験できたのでok。 その辺も次で書いとこ。

参考にさせていただいた皆さまに感謝です。