5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rack middlewareを使ってRailsアプリケーションにBasic認証を組み込んでみた

Last updated at Posted at 2019-12-21

この記事はマネーフォワード アドベントカレンダー21日目の記事です。

Railsエンジニアの @kamillle です。

今回はRack middlewareでBasic認証をRailsのアプリケーションに組み込んでみました。

RailsでBasic認証をどうやって実装するか

Googleで rails basic auth とググると api.rubyonrails.orgドキュメントがヒットし、http_basic_authenticate_withにnameやpasswordというkey名を含んだHashを渡すと、そのコントローラーのアクションに対してBasic認証がかけられることがわかりました。

一行でかけるのでRailsぽくていいなーと思ったですが、同時に下記の違和感を覚えました。

  • リクエストがコントローラーに来る前に解決すべきことなのかなと思った
  • コントローラーの継承関係を間違うと一部のControllerにBasic認証がかかってなかったってことが起きそう
    • テスト書いておけばいいんですが、全コントローラーのrequest specにBasic認証のテスト書くのもめんどくさい、忘れそう

Rackがあるじゃないか

Rack middlewareでBasic認証の機構を実装し、 @app.call(env) する前にBasic認証することができればRack側で処理が完結するためコントローラーにリクエストが行くこともないし、全エンドポイントに対してBasic認証をかけることができるので、アプリケーションの開発時に認証のことを気にする必要がなくなるんじゃないかなと考えました。

Basic認証のロジックをオレオレで実装したくなかったので、 Rack basic auth とかでググってると Rack::Auth::Basic というクラスを見つけました。

このクラスはRFCに沿った形でBasic認証を実装してくれているので、オレオレなことをしなくていいし、使うのも簡単にできそうだったので早速やってみました。

このようなRack middlewareを実装し、

# lib/middlewares/basic_auth_middleware.rb 

module Middlewares
  class BasicAuthMiddleware
    def initialize(app)
      @app = app
    end

    def call(env)
      Rack::Auth::Basic.new(@app) do |username, password|
        username == 'username' && password == 'password'
      end.call(env)
    end
  end
end

それをミドルウェアスタックに追加しました

# config/application.rb

...

require_relative '../lib/middlewares/basic_auth_middleware.rb'

...

module RackBasicAuth
  class Application < Rails::Application
    ...
    ...
    
    config.middleware.use(::Middlewares::BasicAuthMiddleware)
  end
end

ここまで実装してRailsのサーバーを立ち上げてみました

image.png

:tada:

今回Basic認証を実装したアプリケーションは下記のリポジトリで公開しています。
https://github.com/kamillle/rack_basic_auth

おわりに

Rack::Auth::Basicを使うことでも簡単にBasic認証をアプリケーションに組み込むことができました。

今までRack middlewareを実装したことはなかったのですが、Rails側にリクエストを渡す前にリクエストの解析が可能になるので便利だな〜と思いました(弊社のGitHubのOrganization内のコードを見てみると、一部のエンドポイントにのみIP制限をかけるためにRackを使っているプロジェクトがありました)。

5
2
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
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?