【無職に転生 ~ 就職するまで毎日ブログ出す③】【Rails】sorceryを使ったSlackログイン①
はじめに
こんにちは、大ちゃんの駆け出し技術ブログです。
タイトルにあるとおり【無職に転生 ~ 就職するまで毎日ブログ出す】というチャレンジをしています!!!大人気アニメのタイトルをまるパクリした毎日投稿チャレンジです。
RailsやらRubyやらSQLやらその他Webの知識やらが色々と抜け落ちているのを感じており、知識の定着のためにもアウトプットする機会を増やすためです。加えて、退職して文字通り無職に転生しましてプロニートになり、毎日時間に余裕ができたので引き締めるためにも毎日投稿を思い至りました!
【投稿内容】
- SQLの難しい処理 (副問合せ、JOINとか複雑な処理が書けない)
- Rails全般 (純粋に必要な知識が多すぎる、網羅的な理解が足りない)
- Rubyのあまり使わないメソッドや記述方法 (あまり重要ではないけど特に)
- Web知識全般 (クッキーやら、セッションやらなんとなくで理解しているものの自分の言葉で説明できない)
- 書籍 (スタートアップ企業に勤めるので、自分が会社に与える影響やパフォーマンスを高めるためビジネス書を読んでいきます。)
本記事でやること
本日はログインgemであるsorceryを使用してSlackログインを実装する記事を書いていきたいと思います!しかし、かなりやることが多いので二回の記事に分けて行いたいと思います!
SlackログインはSorceryでできるようになった!
実は自分がslackログインを実装したのはdeviseとomniauthのgemを組み合わせで行いました。理由としてはsorceryではエラーが起きていたからです。自分は1、2週間かけてsorceryでslackログインができない理由を調査したことがあります。しかし、どうやってもできなかったので明らかにgem側の問題と結論づけました。というのもslack.rbというsorceryのslack認証ファイルの更新が5年前で止まっていたからです。
しかし、最近なぜか更新されていることを発見し、Pull Requestが投げられていることを確認しました!
これでsorceryでもslackログインができるようになったらしいので自分も本当にできるようになったか確認したところ、しっかりとできるようになっていました!!!!そのため、この記事でその方法を詳しく紹介します!
セットアップ
Slackログインを実装する前に、ユーザーモデルの作成など必要な設定をしておきます。基本的には公式と同様の流れで設定を行います。
GitHub - Sorcery/sorcery: Magical Authentication
gem 'sorcery'
$ bundle install
下記コマンドを実行してマイグレーションファイルやsorceryの設定ファイルを作成
$ rails generate sorcery:install Running via Spring preloader in process 74291 create config/initializers/sorcery.rb generate model User --skip-migration rails generate model User --skip-migration Running via Spring preloader in process 74315 invoke active_record create app/models/user.rb invoke test_unit create test/models/user_test.rb create test/fixtures/users.yml insert app/models/user.rb File unchanged! The supplied flag value not found! app/models/user.rb create db/migrate/20211003000947_sorcery_core.rb
作成されたマイグレーションファイルは以下のようになります。
class SorceryCore < ActiveRecord::Migration[6.1] def change create_table :users do |t| t.string :email, null: false t.string :crypted_password t.string :salt t.timestamps null: false end add_index :users, :email, unique: true end end
変更は特に必要ないのでそのままrails db:migrateします。
$ rails db:migrate
マイグレーションファイルの設定に合わせてモデルのファイルにもバリデーションを設定しておきます。
class User < ApplicationRecord authenticates_with_sorcery! validates :email, uniqueness: true, presence: true validates :password, presence: true end
ここまでで必要な設定は完了です!
Slack Developersでの設定
まず下記ページにアクセスします。
Slack API: Applications | Slack
下記のような画面になっているので、上部にある「Create New App」をクリックします。
すると以下のようなモーダルが開きました。
Choose how you’d like to configure your app’s scopes and settings.
「アプリのスコープや設定をどのように設定するかを選択してください。」と説明されています。ここではSlack標準の設定である「From scratch」を選択します。
次に別のモーダル が開きアプリの名前と開発ワークスペースを選択します。
アプリの名前は分かりやすいものにしておきます。
- App Name → 「slack-sorcery-login」
開発ワークスペースとはSlackアプリを開発する際に使用するワークスペースです。既に参加しているワークスペースでも構いませんが、アプリように新しく開発ワークスペースを作成したほうがいいと思います。ワークスペースの作成方法については以下のリンクから作成してください。
自分は新しく「slack-sorcery-login」をいうワークスペースを作成して、それを開発ワークスペースとして選択しました。
- Pick a workspace to develop your app in: → 「slack-sorcery-login」
最後に「Create App」を押してアプリを作成します。成功すると下記のようなSlack Appの開発画面に遷移します。これでアプリの作成は完了です。
最後にClient IDとClient Secretを確認します。上記の画面を下にスクロールすると確認できます。後ほどこちらは使用します。
Slackログイン用のファイル設定
アプリを作成できればいよいよSorceryのSlack認証機能を実装します。基本的にはSorceryの公式の外部認証のwikiに沿って実装します。
Authenticationテーブル & モデルの作成
External · Sorcery/sorcery Wiki
最初に外部認証用のテーブルを作成します。下記コマンドでマイグレーションファイルを作成します。
$ rails g sorcery:install external --only-submodules gsub config/initializers/sorcery.rb File unchanged! The supplied flag value not found! app/models/user.rb create db/migrate/20211003005016_sorcery_external.rb
作成されたマイグレーションファイルは下記になります。
class SorceryExternal < ActiveRecord::Migration[6.1] def change create_table :authentications do |t| t.integer :user_id, null: false t.string :provider, :uid, null: false t.timestamps null: false end add_index :authentications, [:provider, :uid] end end
providerとは外部認証を提供しているアプリを指します。Twitter、Facebook、LINEなどが挙げられます。そしてマイナーではありますがSlackもその中の一つです。
変更は特に必要ないのでそのままrails db:migrateします。
$ rails db:migrate
次に作成したauthenticationsテーブルに合わせてモデルも作成します。理由はわからないのですが、rails g sorcery:install external --only-submodules
ではモデルのファイルは作成されません。よってモデルは別で作成する必要があります。
それではモデルを作成します。マイグレーションファイルはもう既に作成しているので、--migration=false
オプションを付けています。
$ rails g model Authentication --migration=false
Authenticationモデルにbelongs_to :user
を追加
# app/models/authentication.rb class Authentication < ActiveRecord::Base belongs_to :user end
Userモデルにはhas_many :authentications, dependent: :destroy
とaccepts_nested_attributes_for :authentications
を追加
# app/models/user.rb class User < ApplicationRecord authenticates_with_sorcery! validates :email, uniqueness: true, presence: true validates :password, presence: true has_many :authentications, dependent: :destroy accepts_nested_attributes_for :authentications end
Sorcery.rbの設定
次にsorcery.rb
でSlackの認証の設定を記述します。sorcery.rb
で「Slack」と検索すると下記の部分が確認できます。
# config.slack.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=slack" # config.slack.key = '' # config.slack.secret = '' # config.slack.user_info_mapping = {email: 'email'}
コメントアウトを外しconfig.slack.key
にはClient ID、config.slack.secret
にはClient Secretを記述します。しかし、直書きするのはよくないので環境変数はcredentialsに定義します。
config.slack.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=slack" config.slack.key = Rails.application.credentials.dig(:slack, :clinet_id) config.slack.secret = Rails.application.credentials.dig(:slack, :client_secret) config.slack.user_info_mapping = {email: 'email'}
credentialsの編集方法は下記Qiitaを参照ください。
Rails5.2から追加された credentials.yml.enc のキホン - Qiita
$ EDITOR="vi" bin/rails credentials:edit
下記のように記述します。
slack: client_id: 2572424345441.2562011521556 client_secret: 6627c1e772a94532566a2c8588927608client_secret
また、どの外部認証を使うかを明記する必要があるため、sorcery.rb
の83行目のコメントアウトされている部分のコメントアウトを外し、slackを追加します。
config.external_providers = [:slack]
また、「user.authentications_class」とsorcery.rbで検索し、外部認証のクラスを明記するために下記のようにAuthenticationクラスを指定します。
# --- user config --- config.user_config do |user| ... # -- external -- user.authentications_class = Authentication ... end
適当なログインページを作成
現状どこにもviewを書いていないのでログインページを適当に作ります。
ログインページを適当に追加
現状どこにもviewを書いていないので、ログインするためのページを適当に作ります。
$ rails g controller home index
次にコントローラーを編集します。sorceryのヘルパーメソッド、require_login
を追加します。
# app/controllers/home_controller.rb class HomeController < ApplicationController skip_before_action :require_login def index ;end end
# app/controllers/application_controller.rb class ApplicationController < ActionController::Base before_action :require_login end
routes.rb
にHomeControllerのindexアクションをルートパスに指定します。
Rails.application.routes.draw do root to: "home#index" end
viewも作っておきましょう。中身は記述しなくても良いのでファイルだけ作成しておきます。
<!-- app/views/home/index.html.erb -->
本記事での実装はここまでとします!次回でslackログインを最後まで実装します!