Herokuで公開するFlaskアプリにステージング環境でのみBasic認証をかける - 6月 10, 2020 こんにちは、ぐぐりら(@guglilac)です。 [趣味で開発しているアプリ](https://kanji-lyric.herokuapp.com/quiz)の検証のために、Heroku Pipelineを使って、ステージング環境を作ったのですが、ステージング環境は検索に出てきてほしくないので、ステージング環境のみBasic認証をかけました。 Railsでステージング環境のみBasic認証するという記事は多く見かけたのですが、今回はFlaskで書いており、少々調べて実装したため、知見をまとめておこうと思います。 [Heroku で既存の本番環境をコピーしてステージング環境を作る - Qiita](https://qiita.com/ken_c_lo/items/32998d9dd79a15b75c14)にはステージング環境に環境変数を設定すればできるって書いてあるけど、コメントにもあるようにさすがにアプリ側で処理を書かないとだめなはず。 今回アプリはFlaskを使って書いているので、 * [Flaskで Basic認証、Digest認証 - Qiita](https://qiita.com/msrks/items/7de68cde6c3ab9d5e177) * [FlaskでBasic認証 - Study03.net 対シンバシ専用](https://tell-k.hatenadiary.org/entry/20111005/1317781147) このあたりが検索するとでてきます。 最初、一つ目の記事に倣って`flask-httpauth`を使って、二つ目の記事に倣って`views.py`の全てのメソッドの前に実行するメソッドにデコレータをつけて認証を行うように書きました。 つまり、 ```python from flask_httpauth import HTTPBasicAuth app = Flask(__name__) auth = HTTPBasicAuth() users = { "user": "pass" } @auth.get_password def get_pw(username): if username in users: return users.get(username) return None @app.before_request @auth.login_required def before_request(): pass ``` と書いたけど、 これだとステージング環境のときだけBasic認証するという部分をどう書けばいいかわからず。 なんかいいのないかなと思って探すと、 `Flask-BasicAuth`というのがあり、 [Flask-BasicAuth — Flask-BasicAuth 0.2.0 documentation](https://flask-basicauth.readthedocs.io/en/latest/) を読んでみるとぴったりな代物だった。 結局、以下のように実装しました。 ```python # stagingのみbasic認証を掛ける if os.environ["PG_ENV"] == "staging": app.config['BASIC_AUTH_USERNAME'] = os.environ['BASIC_AUTH_USERNAME'] app.config['BASIC_AUTH_PASSWORD'] = os.environ['BASIC_AUTH_PASSWORD'] app.config['BASIC_AUTH_FORCE'] = True basic_auth = BasicAuth(app) ``` ドキュメントにもあるように、 `app.config['BASIC_AUTH_FORCE'] = True`が便利で、 > You might find this useful, for example, if you would like to protect your staging server from uninvited guests. と書いてある通り、ちょうどやりたいことにぴったりでした。 ちなみに、上の認証の設定コードをviews.pyではなく起動ファイルの`app.run()`の前に書いた場合はローカルで環境変数をstagingにして確認すると正しくBasic認証がかかっていましたが、Heroku上では認証が発生しないという現象にちょいハマりました。 ```python from main.views import app if __name__ == "__main__": #ここに書くとハマる app.run() ``` ローカルで確認するときは`python run_app.py`で起動していたのでbasic_authが設定されるのですが、Herokuではデプロイされた時に ``` web: gunicorn run_app:app --log-file - ``` と書かれたProcfileが読み込まれて起動するように設計していたのが原因のようです。 あとは、忘れずにステージング環境の方に環境変数を設定して終わり。 ```bash heroku config:set BASIC_AUTH_USERNAME=xxxxx BASIC_AUTH_PASSWORD=xxxxxxxxxx --app ステージングのアプリ名 ``` 以上です!同じことをしようとしている方は参考にしてみてください〜 この記事をシェアする Twitter Facebook Google+ B!はてブ Pocket Feedly コメント
コメント
コメントを投稿