LoginSignup
24
23

More than 5 years have passed since last update.

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

Posted at

「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
24
23
1

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
24
23