RailsでのDigest認証の実装方法

こんにちは!kossyです!





さて、今回はRailsアプリケーションにDigest認証を実装する方法について、ブログに残したいと思います。

環境
Rails5.1.6
Ruby2.5.1
MacOS High Sierra





Digest認証ってなに?
Webページアクセス時にユーザーIDとパスワードを要求し、一部のユーザーのみに公開するアプリケーションや、
管理者用画面の実装のため等に用いるHTTP認証方式です。

同じHTTP認証方式でBasic認証がありますが、IDとパスワードの送信方法が異なります。

Basic認証の場合


ユーザー名とパスワードを、Base64と呼ばれる変換方式を用いたデータとして送信します。
Basic認証だとユーザーIDとパスワードをBase64で変換した状態で送信しますが、
これはつまり「ユーザーIDやパスワードの情報がほとんど加工されないまま送信される」ので、
通信を傍受された場合に情報が筒抜けになってしまいます。
出典:
Basic認証(基本認証)とDigest認証、それぞれの役割と違いについて | レンタルサーバー比較なび

Digest認証の場合


入力されたユーザーIDとパスワードをハッシュ関数であるMD5を用いて解析されにくい状態で送信する仕組みです。
ユーザーIDとパスワードが加工された状態で送信されるので、通信を傍受された場合でも簡単に解析はできません。
出典:
Basic認証(基本認証)とDigest認証、それぞれの役割と違いについて | レンタルサーバー比較なび

安全性という観点から言えば、パスワードを平文で送信してしまうBasic認証に比べ、
Digest認証の方がセキュアになります。
とはいえ、両認証方式とも、完全にセキュリティ上の問題がないわけではないので、
必要最低限の認証機能を作成中のWebアプリケーションに実装したい場合のみ、
実装するようにした方が無難かもしれません。



実装方法
下記のコードをapplication_controller.rbに追記するだけです。

app/controllers/application_controller.rb

require 'digest/md5'

class ApplicationController < ActionController::Base
  before_action :authenticate

  REALM = 'SecretZone'.freeze
  USERS = { 'user1' => Digest::MD5.hexdigest(['user1', REALM, 'password'].join(':'))}.freeze

  private

  def authenticate
    authenticate_or_request_with_http_digest(REALM) do |username|
      USERS[username]
    end
  end
end

この状態でブラウザにアクセスすると、
パスワードを要求されるようになります。

usernameとパスワードを変更したい場合は、
user1としている部分と、passwordとしている部分を変更します。

app/controllers/application_controller.rb

require 'digest/md5'

class ApplicationController < ActionController::Base
  before_action :authenticate

  REALM = 'SecretZone'.freeze
  USERS = { 'testuser' => Digest::MD5.hexdigest(['testuser', REALM, '12345678'].join(':'))}.freeze

  private

  def authenticate
    authenticate_or_request_with_http_digest(REALM) do |username|
      USERS[username]
    end
  end
end

これで変更できます。


参考にさせていただいた記事
聞いたことがある認証について調べてみた - Qiita
Basic認証(基本認証)とDigest認証、それぞれの役割と違いについて | レンタルサーバー比較なび