Railsで特定のメソッドにBasic認証をかける

More than 3 years have passed since last update.

「gyazo-s3」を作ってみたときに、閲覧時のみBasic認証をかけようとした時のメモ。

どうやらitems_controller.rbにGETとかPOSTする時のメソッドが書いてあるみたいなので確認します。


app/controllers/items_controller.rb

class ItemsController < ApplicationController

before_filter :authenticate!, only: [:create, :destroy]
before_action :set_item, only: [:show, :destroy]

# GET /
def index
@items = Item.all.page params[:page]
end

# GET /huge.img
def show
url = @item.image.url
if url.include?('http')
# production s3
data = open(url)
send_data data.read, type: @item.image_content_type, disposition: 'inline'
else
# development,test local
url = Rails.root.join('public/' + url.gsub!(/\?.+/, ''))
send_file url, type: @item.image_content_type, disposition: 'inline'
end
end

# POST /items
def create
item = Item.create_with_imagedata(params[:imagedata])
render text: "#{request.protocol}#{request.host_with_port}/#{item.image_file_name}"
end

# DELETE /huge.img
def destroy
@item.destroy
render text: 'destroy'
end

private

def authenticate!
if Rails.configuration.gyazo_id && params[:id] != Rails.configuration.gyazo_id
raise 'ID is incorrect'
end
end

def set_item
filename = "#{params[:name]}.#{params[:format].to_s}"
@item = Item.find_by_image_file_name(filename)
raise 'not item' if @item.nil?
end
end


まず、ベーシック認証に関する定義を書かなければいけないので、次のように記述します。

ID/Pass はHerokuの環境変数を使います。

  def basic_auth

authenticate_or_request_with_http_basic do |user,pass|
user == ENV["BASIC_AUTH_USER"] && ENV["BASIC_AUTH_PASSWORD"]
end
end

次に、一覧と画像を表示するときに使っているindexshowメソッドを使うときにベーシック認証をかける記述を追加します。

  before_filter :basic_auth, only: [:index, :show]

まとめるとこんな感じ。


app/controllers/items_controller.rb

class ItemsController < ApplicationController

before_filter :basic_auth, only: [:index, :show]
before_filter :authenticate!, only: [:create, :destroy]
before_action :set_item, only: [:show, :destroy]

def basic_auth
authenticate_or_request_with_http_basic do |user,pass|
user == ENV["BASIC_AUTH_USER"] && ENV["BASIC_AUTH_PASSWORD"]
end
end

# GET /
def index
@items = Item.all.page params[:page]
end

# GET /huge.img
def show
url = @item.image.url
if url.include?('http')
# production s3
data = open(url)
send_data data.read, type: @item.image_content_type, disposition: 'inline'
else
# development,test local
url = Rails.root.join('public/' + url.gsub!(/\?.+/, ''))
send_file url, type: @item.image_content_type, disposition: 'inline'
end
end

# POST /items
def create
item = Item.create_with_imagedata(params[:imagedata])
render text: "#{request.protocol}#{request.host_with_port}/#{item.image_file_name}"
end

# DELETE /huge.img
def destroy
@item.destroy
render text: 'destroy'
end

private

def authenticate!
if Rails.configuration.gyazo_id && params[:id] != Rails.configuration.gyazo_id
raise 'ID is incorrect'
end
end

def set_item
filename = "#{params[:name]}.#{params[:format].to_s}"
@item = Item.find_by_image_file_name(filename)
raise 'not item' if @item.nil?
end
end