0
0

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 3 years have passed since last update.

Basic認証 PART 2

Last updated at Posted at 2021-03-11

##Basic認証のコードを改良する
前回の内容で、Basic認証をRailsアプリケーションに導入することができましたね。
ですが、現状のコードには次の2つの問題点があります。

###(1)ユーザー名・パスワードがコードに記述されている
Basic認証を実装しました!!パスワードはGithubに載ってます!!ってなったらセキュリティの意味ないですよね。(笑)
Github上の公開リポジトリでソースコードを管理している場合、コードを読める何者かに不正にBasic認証を突破される可能性があります。対策としては、コードに直接ユーザー名とパスワードを記述するのではなく、環境変数を利用する実装に切り替えて対処しましょう。

###(2)全ての環境でBasic認証を要求してしまう
Basic認証を使ってアクセスを制限したいのは、アプリケーションがデプロイされている本番環境ですよね。ですが、現在のコードでは、basic_authメソッドを使いたい環境を特に指定していないため、本番環境・テスト環境・開発環境の全てでBasic認証が働きます。開発中には自分の首を締めることにもなりますので、本番環境のみでBasic認証をするようにコードを書き換えましょう。

###ユーザー名・パスワードを環境変数にしよう
basic_authメソッド内で直接記述しているユーザー名とパスワードを環境変数に格納しましょう。

####ローカル環境の設定

ターミナル
$ vim ~/.bash_profile

# .bash_profileを開いたら、「i」とタイプしてインサートモードに移行

# .bash_profileの内部に次の記述を追加
export BASIC_AUTH_USER='admin'
export BASIC_AUTH_PASSWORD='2222'
# 記述を追加したら、escキーを押してインサートモードを抜け、「:wq」と入力して保存して終了する

# .bash_profileを再読み込みし、定義した環境変数を有効にする
$ source ~/.bash_profile

####本番環境の設定

ターミナル
# 本番環境
$ ssh -i [ダウンロードした鍵の名前].pem ec2-user@[作成したEC2インスタンスと紐付けたElastic IP]
(ダウンロードした鍵を用いて、ec2-userとしてログイン)
$ sudo vim /etc/environment
# iを押してインサートモードに移行し、下記を追記する。既存の記述は消去しない。

BASIC_AUTH_USER='admin'
BASIC_AUTH_PASSWORD='2222'

# 編集が終わったらescapeキーを押してから:wqと入力して保存して終了
ターミナル
# 本番環境
# 編集した環境変数を適用するために一旦ログアウトします。
$ exit
$ ssh -i [ダウンロードした鍵の名前].pem ec2-user@[作成したEC2インスタンスと紐付けたElastic IP]
# 環境変数が適用されているか確認しましょう。
$ env | grep BASIC_AUTH_USER
$ env | grep BASIC_AUTH_PASSWORD

環境変数を記述するファイルが異なる理由についてはS3を使って画像をアップロードするを参考にしてください。

BASIC_AUTH_USERとBASIC_AUTH_PASSWORDという名前で、それぞれユーザー名とパスワードを定義することができました。続いて、この環境変数をRailsアプリケーション側で読み込むように記述を変更しましょう。

controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :basic_auth
  protect_from_forgery with: :exception

  private

  def basic_auth
    authenticate_or_request_with_http_basic do |username, password|
      username == ENV["BASIC_AUTH_USER"] && password == ENV["BASIC_AUTH_PASSWORD"]←この部分を変更する
    end
  end
end

これで、環境変数を使って、Basic認証を行えるユーザー名とパスワードを定義することができました。もう一度Basic認証を試みて、環境変数として設定したユーザー名とパスワードでログインができれば、正しく実装できています。

環境変数は、環境ごとに設定する必要があります。開発環境でBasic認証をしたい場合はローカルの~/.bash_profileを、本番環境でBasic認証をしたい場合は本番サーバーにssh接続して、~/.bash_profileを編集しましょう。

###本番環境のみでBasic認証をするようにしよう
続いて、本番環境のみでBasic認証をするようにしましょう。
まずはconfig/deploy配下のproduction.rbに追記します。(すでに追加済なら作業不要です)

config/deploy/production.rb
# server "db.example.com", user: "deploy", roles: %w{db}
server "(EC2のIPアドレス)", user: "ec2-user", roles: %w{app db web}

set :rails_env, "production"
set :unicorn_rack_env, "production"

# role-based syntax
# ==================

これで、unicornが現在の環境を本番環境として認識するようになります。
さらにapplication_controllerの記述を少し変更します。

app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :basic_auth, if: :production?←ここを定義
  protect_from_forgery with: :exception

  private

  def production?←このメソッドを定義
    Rails.env.production?
  end

  def basic_auth
    authenticate_or_request_with_http_basic do |username, password|
      username == ENV["BASIC_AUTH_USER"] && password == ENV["BASIC_AUTH_PASSWORD"]
    end
  end
end

production?というメソッドを定義し、現在の環境が本番環境ならtrue、そうでないならfalseを返すように、Rails.env.production?と記述しています。そして、before_action :basic_auth の後に、 if: :production?と記述することによって、本番環境のみでbasic_authメソッドが実行されるようになります。

###Basic認証の動作確認を行う
続いて、Basic認証の動作確認をします。Basic認証を実装したブランチをマージしたら、Capistranoを用いたデプロイを行ないましょう。初めてBasic認証の動作確認をする時だけ、以下のようにデプロイをしてunicornの停止と起動も行ってから動作確認します。

開発端末上での操作
$ bundle exec cap production deploy unicorn:stop
(デプロイ完了まで待ち、完了後に以下を実行)

$ bundle exec cap production deploy unicorn:start

もしうまく動かない場合は、一度AWSのコンソールからEC2を再起動し、nginx、MySQL、Unicornを手動で順番に再起動してください。
なおUnicornは以下のように起動しましょう。

EC2上での操作
$ cd /var/www/アプリケーション名/current
$ bundle exec unicorn -c /var/www/アプリケーション名/current/config/unicorn.rb -E production -D

##Basic認証の問題点
Basic認証は少ない手間で認証を実現できるので、便利なのですが、安全性という観点から、完全に信頼できる認証方式ではありません。HTTP通信で定義されている仕様上、ユーザー名とパスワードが通信経路上にそのまま送られるため、漏洩のリスクがあります。また、ログアウトの概念が定義されていないため、もし必要になる場合は自力で実装する必要があるほか、複数のサーバーを跨いだ認証が難しいといった特徴も問題になります。

あくまで、必要最低限の認証機能を作成中のWebアプリケーションに実装したい場合のみ、Basic認証を利用するようにしましょう。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?