Heroku上にデプロイするSinatraで、Basic認証を使ってアクセス制限をかける方法について調べたのでメモ。特にHerokuに限らない方法だとは思うけど。ここだけの秘密だけど、最初普通のウェブサイトのように.htaccess
と.htpasswd
を用意して、Herokuアプリ直下またはpublic
ディレクトリに入れればいけるんだろうと思って、heroku console
から pwd
とか実行してパスを取得して.htaccess
に.htpasswd
までのパスを書いて…とか壮大に明後日の方向な手順を踏んでた。
SinatraでのBasic認証の方法は全然違って、Rackの機能を使うみたい。
サイト全体をアクセス制限
Sinatraアプリの起動ファイル(config.ru
から呼び出しているrbファイル)のどこかに、以下のような感じで書けばおk あ、もちろんトップレベルに書く必要はある。あとconfigure
メソッド内でもいいみたい。
use Rack::Auth::Basic do |username, password|
username == ENV['BASIC_AUTH_USERNAME'] && password == ENV['BASIC_AUTH_PASSWORD']
end
ユーザー名やパスワードは直に書いてもいいんだけど、Herokuの環境変数ENV
に入れておくのがセキュリティ的にはよさそうかな。ローカルで試すときに煩雑になるデメリットはあるけど。ここらへん、いい方法あるのかな?
$ heroku config:add BASIC_AUTH_USERNAME="hoge" BASIC_AUTH_PASSWORD="fuga"
これでサイト上のどのページにアクセスしてもBasic認証のウィンドウが開く。
特定のパスだけ部分的にアクセス制限
特定のパスだけアクセス制限を掛ける場合は、helpers
メソッドでヘルパー化して、それを呼び出すのが良いみたい。
require 'rubygems'
require 'sinatra'
helpers do
def protect!
unless authorized?
response['WWW-Authenticate'] = %(Basic realm="Restricted Area")
throw(:halt, [401, "Not authorized\n"])
end
end
def authorized?
@auth ||= Rack::Auth::Basic::Request.new(request.env)
username = ENV['BASIC_AUTH_USERNAME']
password = ENV['BASIC_AUTH_PASSWORD']
@auth.provided? && @auth.basic? && @auth.credentials && @auth.credentials == [username, password]
end
end
get '/' do
'アクセス制限なし'
end
get '/protect' do
protect!
'アクセス制限あり'
end
実際やってみたページはこれ。ユーザー名とパスワードは上述のとおりhoge
とfuga
で。
Basic認証を行う簡単なサンプル - うなの日記 Sinatra: Frequently Asked Questions Sinatraで使える認証ライブラリのメモ - Hello, world! - s21g