[Ruby on Rails]SendGridを用いたパスワードリセット機能の実装

はじめに

はじめまして!運営メンバーのなかやん(@nakayarn)といいます!今回、TechBullコミュニティ内で、会員管理システムを作るにあたって、SendGridを使用したパスワードリセット機能を実装させて頂きました。その内容をブログに記載させていただきます。

会員管理システムについては@adachin0817さんのスライドを参考に!

自己紹介

@adachin0817さんとはエンジニアイベントを通じて知り合い、コミュニティに参加しました。現在は、未経験エンジニア向けの研修や、プログラミングスクールでの質問対応・就職支援を担当しております。メインの開発言語はRuby on Railsで、時々Javaも使用。サービス全体の構造を理解したいという思いから、フロントエンドやクラウドなど幅広い分野を横断的に学習中です!よろしくお願いします!

ローカル開発環境

  • バックエンド:Ruby on Rails(API)
  • フロントエンド:React
  • 開発環境:Docker
  • 前提条件
    • deviseでのログイン機能を実装済みの状態からパスワードリセット機能を実装
    • .envファイルで環境変数を扱える環境が整っている

バックエンドの内容のみを記載いたします。セキュリティに関しては、以下の点に注意して実装しました。

  • パスワードリセット用トークンは10分で有効期限が切れるようにする
  • 一度使用したトークンは再利用できないようにする

SendGrid APIとは?

メール配信に特化したクラウドプラットフォームです。高い配信率を誇るそうで、今回はパスワードリセット用のメール配信に使用します。無料トライアル期間は60日間となっており、その後は有料プランに移行する必要があります。

https://sendgrid.com/en-us

実装

  • SendGrid APIキーの取得

SendGridのWebサイトに登録を行い、APIキーを生成します。

「API Keys」>「Create API Key」からAPIキーを生成することができます。

権限は「Full Access」または「Mail Send」権限を付与します。セキュリティの観点から「Mail Send」権限を推奨します。

設定したメールアドレスに認証メールが届くので、認証が完了すればAPIを使用することができます。

  • 環境変数の設定

APIで使用するAPIキーとメールアドレスは.envファイルで管理するため、環境変数を設定します。

  • .env

    • gemの導入

Ruby用の専用gemが提供されているので、sendgrid-rubyを使用します。また、メール送信確認で使用するletter_opener_webというgemも一緒に導入します。

Gemfileに以下を追記して、bundle installを実行します。

    • Gemfile

  • ハッシュ化したトークンと発行日時を保存するカラムの作成

トークンの発行や管理を行うため、必要なカラムを追加します。ターミナルで以下のコマンドを実行してマイグレーションファイルを作成します。(既にusersテーブルが存在するので、カラムの追加のみ)

作成されたマイグレーションファイルに以下のコードを記載します。

マイグレーションを実行します。

schema.rbファイルを確認し、reset_password_tokenreset_password_sent_atが追加されていることを確認します。

  • パスワードリセット用のコントローラーの作成

このコントローラーで実装したい機能は以下の通りです。

1. リセットメール送信 (create)
メールアドレスを受け取ってリセットメールを送信

2. トークン有効性確認 (show)
リセットリンクの有効性のチェック

3. パスワード更新 (update)
新しいパスワードで更新実行&トークンのクリア

  • app/app/controllers/api/password_resets_controller.rb

セキュリティの観点から、メールアドレスを送信した際に、ユーザーの有無に関わらず同じレスポンスを返すようにしました。

  • モデルにメソッドの追加

トークンの有効期限をチェックするメソッドはuserモデルに記載します。

  • app/models/user.rb

  • ルーティングの設定

ルーティングはcreate・show・updateのみ作成します。

  • ActionMailerの設定

メールを送信するための設定を行います。APIのメールアドレスが変更される可能性があるため、環境変数を使用します。

  • app/mailers/application_mailer.rb

親クラス:送信者メールアドレスのデフォルト設定

  • app/mailers/user_mailer.rb

子クラス:パスワードリセットメールの設定

  • 環境変数の設定(追記)

フロントエンドのURLを環境によって使い分ける設定を行ったため、.envファイルに以下の環境変数を追加します。

  • パスワード再設定用メールテンプレートの作成

送信するメールのテンプレートを作成します。ここで、app/mailers/user_mailer.rbで設定した@userと@reset_urlの変数を使用します。

  • app/views/user_mailer/password_reset.html.erb

  • 開発環境用のメール送信設定

開発環境でメールを送信できるようにするために設定を行います。

  • config/environments/development.rb

letter_opener_webというgemを使用してメール送信テストを実施します。

curlを使用したAPIエンドポイントテスト

まだフロントエンド部分を使用していないため、curlコマンドを使用して動作確認を行います。

  • 別のターミナルでRailsコンソールを起動

  • メール送信

コマンドを実行後、設定したメッセージ {“message”: “パスワードリセット処理が完了しました。メールをご確認ください。”} が返ってくればOK!

letter_opener_webをブラウザで開いてメールに記載のトークンを確認します。

  • トークンの有効性の確認

メールで確認したトークンを使用して有効性を確認します

  • パスワード更新

newpassword123という値でパスワードを更新します。

パスワードが更新され、 {“message”:”パスワードが正常に更新されました”} というメッセージが表示されれば成功です!

おわりに

SendGrid APIを使用したパスワードリセット機能を実装したのが初めてだったので、とても勉強になりました。また、TechBullコミュニティの方々からコードレビューをいただき、大変勉強になりました!!

SendGrid APIは長めの無料期間があるので、ご興味のある方は是非実装してみてください。長い文章をお読みいただき、ありがとうございました!

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール