LoginSignup
1
1

More than 1 year has passed since last update.

ハンズオン rails new から OAuth2 を使った機能を実装するまで

Posted at

今年は OAuth2 の仕組みを使ってユーザーに認可を求める Web アプリをたくさん書きました。この振る舞いを実現するために、難しいことは必要ないのですが、いくつかの仕組みをまたいだ作業が必要です。ということで手順のまとめ記事です。

ところで、 ruby で google-apis-ruby-client を使うのが半端なく面倒くさいという記事があるようですが、たぶんどの言語、どのライブラリを使ってもこの手順になるんじゃないかと思っています。

ここでは、 hampton という名前のプロジェクトを生成していきます。以下のコマンドは、 Rails のプロジェクトを生成し、コードを一式そろえてくれます。Rails プロジェクトのフォルダ構造や、どこになにが書いてあるとかは、 https://guides.rubyonrails.org/getting_started.html を読むと良いと思いますが、いまは気にせずに作業していきましょう。

プロジェクトを生成してエディタで開く

以下のコマンドを実行します。

rails new hampton

画面がこういう感じになると思います。

スクリーンショット 2021-12-31 13.17.46.png

生成したプロジェクトの中に cd で移動して、テキストエディタ (Visual Code Studio) を起動します。

cd hampton
code .

スクリーンショット 2021-12-31 13.19.06.png

以下のコマンドを実行して、開発用サーバーを起動します。

rails server

スクリーンショット 2021-12-31 13.27.24.png

このような画面になったら、サーバーが起動しています。ブラウザで http://localhost:3000 を開きましょう。

スクリーンショット 2021-12-31 13.28.27.png

この画面が表示されていれば、正しく動作しています。ここまでで準備ができたので、これからコードを書いていきます。

まずユーザーを登録できるようにする

rails generate scaffold user email:string name:string
rake db:migrate

さきほどと同じくブラウザで開発用のサーバーを開くのですが、先ほどの URL と違い、 http://localhost:3000/users を開きます。すると下の画面が表示されます。

スクリーンショット 2021-12-31 13.28.31.png

ユーザーを登録しましょう。

スクリーンショット 2021-12-31 13.31.49.png
スクリーンショット 2021-12-31 13.45.26.png

google-api-client という gem を追加する

gem 'google-api-client'
bundle install

飛ばす部分をつくる

rails generate controller oauth2_sessions 

これが

  resources :users

こうなる

  resources :users do
    get "oauth2_sessions" => "oauth2_sessions#new"
    get "oauth2_callback" => "oauth2_sessions#callback", on: :collection
  end

これが

class Oauth2SessionsController < ApplicationController

end


class Oauth2SessionsController < ApplicationController

  def new
  end

end

さっきの画面

スクリーンショット 2021-12-31 13.45.26.png

この画面の URL の末尾に /oauth2_sessions を付け足します。

スクリーンショット 2021-12-31 13.45.35.png

この画面が出ると思います。これはエラー画面ですが、正解です。

スクリーンショット 2021-12-31 13.45.12.png

Token の保存場所をつくっておく

(この部分は以前にActiveRecord を googleauth の TokenStore として使う方法という記事に書いたものとほぼ同じ内容です)

rails generate model google_auth_token token_key:string client_id:string 
google_auth_token.rb
class GoogleAuthToken < ApplicationRecord
  validates :token_key, presence: true, uniqueness: true
  validates :client_id, presence: true
end
active_record_token_store.rb
class ActiveRecordTokenStore < Google::Auth::TokenStore
  def load id
    record = GoogleAuthTokenStore.find_by! token_key: id
    record.to_json
  end

  def store id, token
    json = JSON.parse(token)
    client_id = json["client_id"]
    access_token = json["access_token"]
    refresh_token = json["refresh_token"]
    expiration_time_millis = json["expiration_time_millis"]
    record = GoogleAuthToken.find_or_initialize_by token_key: id, client_id: client_id, access_token: access_token, refresh_token: refresh_token, expiration_time_millis: expiration_time_millis
    record.save
  end

  def delete id
    record = GoogleAuthToken.find_by! token_key: id
    record.destroy
  end
end



class Oauth2SessionsController < ApplicationController

  def new
    @user = User.find(params[:user_id])

    key = ENV.fetch 'GOOGLE_CREDENTIALS_KEY'
    secret = ENV.fetch 'GOOGLE_CREDENTIALS_SECRET'
    callback = ENV.fetch 'GOOGLE_CREDENTIALS_CALLBACK'
    token_store = ActiveRecordTokenStore.new

    client_id = Google::Auth::ClientId.new key, secret
    user_authorizer = Google::Auth::UserAuthorizer.new client_id, token_store, callback

    redirect_to user_authorizer.get_authorization_url
  end

end



GCP で鍵を生成して、環境変数から読み込ませる

GOOGLE_CREDENTIALS_KEY=xxxxxxxxxxxxxxxxxxxxx GOOGLE_CREDENTIALS_SECRET=xxxxxxxxxxxxxxxxxxxxxxx GOOGLE_CREDENTIALS_CALLBACK=http://localhost:3000/users/oauth2_callback rails server

コールバック側を実装する

  def callback
    key = ENV.fetch 'GOOGLE_CREDENTIALS_KEY'
    secret = ENV.fetch 'GOOGLE_CREDENTIALS_SECRET'
    callback = ENV.fetch 'GOOGLE_CREDENTIALS_CALLBACK'
    token_store = ActiveRecordTokenStore.new

    client_id = Google::Auth::ClientId.new key, secret
    user_authorizer = Google::Auth::UserAuthorizer.new client_id, token_store, callback
    user_authorizer.get_and_store_credentials_from_code code: params[:code]

    redirect_to root_path
  end

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1