みんなのちからになりたい

コピペでブログラムつくっていきたい

sinatraでtwitterにsign inする

twitterを使ってなんかするweb siteを作るため、まずはsign inする仕組みを作ってみる。
2年くらいまえにざっくりしたものを作ったことがあるのでなんとなくは理解してるけど再勉強する。

要は

  • OAuth使ってtwitterと認証
  • 認証成功するとaccess_tokenもらえる
  • callbackへ飛ぶ

ということになる。

rubyでOAuthする方法はいくつかあるみたいだけど、omniauthがスタンダードっぽいのでこれでやってみる。

やり方はそのものずばりがSinatra Recipesにあった。

Sinatra Recipes

まずは先にtwitterにアプリの登録をしておく。
いまはcallbackに適当なの書いておくとsuspendされるみたいなので(http://localhostとかやばいらしい)127.0.0.1とかその辺を登録しておく。

まずは写経でやってみる。

require "bundler/setup"

require "sinatra/base"
require "omniauth-twitter"

class MyApp < Sinatra::Base

  configure do
    enable :sessions

    use OmniAuth::Builder do
      provider :twitter, ENV['CONSUMER_KEY'], ENV['CONSUMER_SECRET']
    end
  end

  before do
    # we do not want to redirect to twitter when the path info starts
    # with /auth/
    pass if request.path_info =~ /^\/auth\//

    # /auth/twitter is captured by omniauth:
    # when the path info matches /auth/twitter, omniauth will redirect to twitter
    redirect to('/auth/twitter') unless current_user
  end

  get '/auth/twitter/callback' do
    # probably you will need to create a user in the database too...
    session[:uid] = env['omniauth.auth']['uid']
    # this is the main endpoint to your application
    redirect to('/')
  end

  get '/auth/failure' do
    # omniauth redirects to /auth/failure when it encounters a problem
    # so you can implement this as you please
  end

  get '/' do
    'Hello omniauth-twitter!'
  end

  helpers do
    # define a current_user method, so we can be sure if an user is authenticated
    def current_user
      !session[:uid].nil?
    end
  end

end

すごい、当たり前だけどなんの問題もなく動く。

ソース読むと、beforeのとこのauthとマッチしたらpassって書いてあるのがなにやってるのかわかんなくて悩んだけど、docみたら次のルートに飛ばすって書いてあったのでなるほどと思った。

Sinatra: README (Japanese)

次に飛ばしてみる。

require "bundler/setup"

require "sinatra/base"
require "omniauth-twitter"

class MyApp < Sinatra::Base

  configure do
    enable :sessions

    use OmniAuth::Builder do
      provider :twitter, ENV['CONSUMER_KEY'], ENV['CONSUMER_SECRET']
    end
  end

  before do
    # we do not want to redirect to twitter when the path info starts
    # with /auth/
    pass if request.path_info =~ /^\/auth\//

    # /auth/twitter is captured by omniauth:
    # when the path info matches /auth/twitter, omniauth will redirect to twitter
    redirect to('/auth/twitter') unless current_user
  end

  get '/umaibou' do
    'umaibou!'
  end

  get '/auth/twitter/callback' do
    # probably you will need to create a user in the database too...
    session[:uid] = env['omniauth.auth']['uid']
    # this is the main endpoint to your application
    redirect to('/')
  end

  get '/auth/failure' do
    # omniauth redirects to /auth/failure when it encounters a problem
    # so you can implement this as you please
  end

  get '/' do
    'Hello omniauth-twitter!'
  end

  helpers do
    # define a current_user method, so we can be sure if an user is authenticated
    def current_user
      !session[:uid].nil?
    end
  end

end

404が出る。
次のルートってなんでもいいんじゃなくてパスに応じた次なのか...
わかるひとはわかるんだろうけどわからないとこういうなんでもないとこではまる。
いまはパスがルートしかないのでとりあえず/*で取ってみる。

require "bundler/setup"

require "sinatra/base"
require "omniauth-twitter"

class MyApp < Sinatra::Base

  configure do
    enable :sessions

    use OmniAuth::Builder do
      provider :twitter, ENV['CONSUMER_KEY'], ENV['CONSUMER_SECRET']
    end
  end

  before do
    # we do not want to redirect to twitter when the path info starts
    # with /auth/
    pass if request.path_info =~ /^\/auth\//

    # /auth/twitter is captured by omniauth:
    # when the path info matches /auth/twitter, omniauth will redirect to twitter
    redirect to('/auth/twitter') unless current_user
  end

  get '/umaibou' do
    'umaibou!'
  end

  get '/*' do
    '*!'
  end

  get '/auth/twitter/callback' do
    # probably you will need to create a user in the database too...
    session[:uid] = env['omniauth.auth']['uid']
    # this is the main endpoint to your application
    redirect to('/')
  end

  get '/auth/failure' do
    # omniauth redirects to /auth/failure when it encounters a problem
    # so you can implement this as you please
  end

  get '/' do
    'Hello omniauth-twitter!'
  end

  helpers do
    # define a current_user method, so we can be sure if an user is authenticated
    def current_user
      !session[:uid].nil?
    end
  end

end

ちゃんと*!が出る、すばらしい。

ということで、次からtwitterにpostしたりいろいろやってみようと思う。