OAuth
TwitterAPI
crystal
CrystalDay 23

CrystalとOAuth認証

RubyでTwitterやFacebookのIDを使ってOAuth認証を行う場合、大体omniauthを使うかと思いますが、Crystalの場合はどうするかというと、multi_authというツールがあります。

https://github.com/msa7/multi_auth

基本的な使い方はREADMEを見たらそのまんまなので、特に苦労することはないですが、環境構築でちょっと手間取ったところがあったので手順の再確認ということで以下に纏めます。
尚今回はTwitterで認証してみます。必要なクレデンシャルは以下のサイトで登録しておきます。

https://apps.twitter.com

CrystakとKemalのバージョン

CrystalとKemalのバージョンは以下の対応で確認しています。

  • Crystal
    • 0.23.1
  • Kemal
    • 0.20.0

仕様の破壊的変更の影響があるので、現時点では上記の組み合わせ以外は動きません。

必要なもの

取り敢えずshard.ymlは以下の感じです。

dependencies:
  kemal:
    github: kemalcr/kemal
    version: 0.20.0
  kemal-session:
    github: kemalcr/kemal-session
  db:
    github: crystal-lang/crystal-db
  pg:
    github: will/crystal-pg
  multi_auth:
    github: msa7/multi_auth

kemal-sessionとdb、pgは取得した情報を保存するのに使ってます。
取り敢えず最低限動かすのに必要なコードの抜粋をすると以下の通りです。

require "kemal"
require "multi_auth"

MultiAuth.config("twitter", ENV["TWITTER_CONSUMER_KEY"], ENV["TWITTER_CONSUMER_SECRET"])

def self.multi_auth(env)
  provider = env.params.url["provider"]
  redirect_uri = "#{Kemal.config.scheme}://#{env.request.host_with_port.as(String)}/multi_auth/#{provider}/callback"
  MultiAuth.make(provider, redirect_uri)
end

get "/multi_auth/:provider" do |env|
  url = multi_auth(env)
  env.redirect(url.authorize_uri)
end

get "/multi_auth/:provider/callback" do |env|
  user = multi_auth(env).user(env.params.query)
  env.redirect "/user" # 認証後に遷移するURL
end

https://apps.twitter.com

で取得した情報の内必要なものは、Consumer Key (API Key)とConsumer Secret (API Secret)になります。
第2引数と、第3引数に設定します。

ログインしたいページに以下のリンクを貼り、画面からクリックで認証が走ります。
<a href="/multi_auth/twitter">Sign in with Twitetr</a>

特に難しいことはないですが、twitterから取得できる情報として

  • nickname(twitter id)
  • uid
  • image_url(iconのURL)

などがあります。