【無職に転生 ~ 就職するまで毎日ブログ出す④】【Rails】sorceryを使ったSlackログイン②
はじめに
こんにちは、大ちゃんの駆け出し技術ブログです。
タイトルにあるとおり【無職に転生 ~ 就職するまで毎日ブログ出す】というチャレンジをしています!!!大人気アニメのタイトルをまるパクリした毎日投稿チャレンジです。
RailsやらRubyやらSQLやらその他Webの知識やらが色々と抜け落ちているのを感じており、知識の定着のためにもアウトプットする機会を増やすためです。加えて、退職して文字通り無職に転生しましてプロニートになり、毎日時間に余裕ができたので引き締めるためにも毎日投稿を思い至りました!
【投稿内容】
- SQLの難しい処理 (副問合せ、JOINとか複雑な処理が書けない)
- Rails全般 (純粋に必要な知識が多すぎる、網羅的な理解が足りない)
- Rubyのあまり使わないメソッドや記述方法 (あまり重要ではないけど特に)
- Web知識全般 (クッキーやら、セッションやらなんとなくで理解しているものの自分の言葉で説明できない)
- 書籍 (スタートアップ企業に勤めるので、自分が会社に与える影響やパフォーマンスを高めるためビジネス書を読んでいきます。)
本記事でやること
本日はログインgemであるsorceryを使用してSlackログインを実装する記事の続きです!前回の記事はしたのリンクから参照ください!
【無職に転生 ~ 就職するまで毎日ブログ出す③】【Rails】sorceryを使ったSlackログイン① - 大ちゃんの駆け出し技術ブログ
Slackログインの実装
いよいよSlackログインを実装します!
コントローラーの作成
Slackログインをするためのコントローラーを作成します。
$ rails g controller Oauths oauth callback
中身は下記のように実装します。下のコードの説明は後ほどSlackログイン実行時に説明しますので今はコピペだけでOKです!
# app/controllers/oauths_controller.rb class OauthsController < ApplicationController skip_before_action :require_login def oauth login_at(auth_params[:provider]) end def callback provider = auth_params[:provider] if (@user = login_from(provider)) redirect_to root_path, notice: "#{provider.titleize}でログインしました" else begin @user = create_from(provider) reset_session auto_login(@user) redirect_to root_path, notice: "#{provider.titleize}でログインしました" rescue StandardError redirect_to root_path, alert: "#{provider.titleize}でのログインに失敗しました" end end end private def auth_params params.permit(:code, :provider) end end
routes.rbの設定
これも公式wikiと同じです。
# config/routes.rb post "oauth/callback", to: "oauths#callback" get "oauth/callback", to: "oauths#callback" get "oauth/:provider", to: "oauths#oauth", as: :auth_at_provider
Bootstrapの追加
ここは飛ばしても問題ないです。後ほどアプリを拡張するかもしれないので念のため入れておきます.
$ bin/yarn add bootstrap@4.4.1 jquery@3.5.1 popper.js@1.16.1
// app/javascript/packs/application.js import "bootstrap" import "bootstrap/scss/bootstrap.scss"
viewにリンクを追加
Slackログイン用のリンクを前回適当に作ったページに追加します。
<%= link_to 'Login with Slack', auth_at_provider_path(provider: :slack), class: "btn btn-primary btn-block" %>
ですが、ログインしたことがわかるようにしたいので下記のように記述してください。ヘルパーメソッドlogged_in?
でログインしていなければリンクを表示、していれば「ログインししました!」というメッセージが表示されます。
<div class="container p-5"> <% if logged_in? %> <div>ログインしました!</div> <% else %> <%= link_to 'Login with Slack', auth_at_provider_path(provider: :slack), class: "btn btn-primary btn-block" %> <% end %> </div>
Ridirect URLの設定
OauthでよくあるRiderect URL(コールバック)を設定します。GitHubやTwitterのdeveloperではlocalhostのURLで指定できますが、SlackではhttpsのURLを指定する必要があります。よってngrokを使用してhttpsのURLを生成します。
ngrokの設定を反映させるために下記の記述をdevelopment.rb
に追加します。
# config/environments/development.rb Rails.application.configure do . . config.hosts << '.ngrok.io' end
ngrokを起動します。
$ ngrok http 3000 ・ ・ Version 2.3.35 Region United States (us) Web Interface http://127.0.0.1:4040 Forwarding http://61f8-111-239-158-158.ngrok.io -> http://localhost:3000 Forwarding https://61f8-111-239-158-158.ngrok.io -> http://localhost:3000
httpsのURLを確認します。自分の場合は下記URLです。
https://61f8-111-239-158-158.ngrok.io
このURLをコピーしてsorcery.rb
を開き、Slackの設定の箇所を探します。そしてconfig.slack.callback_url
の箇所を下記のように設定します。
config.slack.callback_url = "https://61f8-111-239-158-158.ngrok.io/oauth/callback?provider=slack" config.slack.key = Rails.application.credentials.dig(:slack, :client_id) config.slack.secret = Rails.application.credentials.dig(:slack, :client_secret) config.slack.user_info_mapping = {email: 'email'}
設定したURLをコピーします。
https://61f8-111-239-158-158.ngrok.io/oauth/callback?provider=slack
次にSlackの開発ページを開いて左ペインの「OAuth & Permissions」をクリックします。
次に「Redirect URLs」という項目があるのでそこに先ほどコピーしたURLを貼り付けます。
- 「Add New Redirect URL」をクリック
- フォームが出てくるのでそこにコピーしたURLをペースト
- フォームの横にある「Add」をクリック
- 「Save URLs」をクリック
- 「Success!」が表示
これでRedirect URLの設定が完了です。
Slackログインを確認
これで必要な設定は全て完了しましたので早速Slackログインを確認します。ngrokで生成されたURLでブラウザを開きます。
リンクを押すとSlackの認証画面に遷移します。
Slackの認証画面で「許可する」を押します。すると画面に「ログインしました」と表示されます。
ここでログインに失敗する場合、sorceryが最新でインストールされていない可能性があります。つまり、slackログインができない状態のsorceryです。ですので、gemの処理をPRに沿って書き換えましょう。
変更する箇所は1箇所のみです。access_token.get(user_info_path, params: { token: access_token.token })
をaccess_token.get(user_info_path)
に変更します。
# vendor/bundle/ruby/2.6.0/gems/sorcery-0.16.1/lib/sorcery/providers/slack.rb def get_user_hash(access_token) response = access_token.get(user_info_path) auth_hash(access_token).tap do |h| h[:user_info] = JSON.parse(response.body) h[:user_info]['email'] = h[:user_info]['user']['email'] h[:uid] = h[:user_info]['user']['id'] end end
終わりに
Slackログインの記事はほとんどないので実装するのは大変でした💦 このログイン方法が皆さんに使ってもらえたら嬉しいです。ただ現状OauthsControllerの処理について疑問に思っている方も多いと思います。OauthsControllerの処理の説明は長くなるのでまた今度にします!