【豆知識】Google認証APIキーを含む秘匿情報ENVコードで管理。+credentialとの違い

# はじめに
アプリ開発の課題においてGoogle credentialを用いた秘匿情報の設定を実装しましたが、もう一つ広く知られているENVコードというものがあります。今回はこちらの機能を実装した場合はどんな流れになるのか、調べてことをアウトプットしたいと思います。

## 環境
- Windows, WSL
- Docker
- Ruby 3.2.3
- Rails 7.1.3


## **ENVのコードについて**
`ENV`は環境変数を参照するためのRubyの仕組みです。環境変数は、アプリケーションの設定情報を外部から取得するためのもので、セキュリティの観点からも便利なものになります。


## 設定手順
- IDやシークレットについてはこちらの記事を参照にしました
※注意としては「認証済みのリダイレクトURL」は`http://localhost:3000/oauth/callback?provider=google`で

https://zenn.dev/yoiyoicho/articles/c44a80e4bb4515


### 1:Gemfileに必要なGemを用意
```ruby
gem "omniauth-google-oauth2"
gem "omniauth-rails_csrf_protection"
# 今回は'.env'を仮に使う前提なので次のgemも追加
gem "dotenv-rails"
```

※`gem device`についての導入は割愛させていただきます（なるべく公式と最新の記事を参考に）

https://github.com/heartcombo/devise#getting-started

https://qiita.com/cigalecigales/items/f4274088f20832252374

- Gemfileに追加ができたらbundle install
  ```ruby
  $ bundle install

  # '.env'を使う方は以下も実施(アプリのディレクトリで)
  $ touch .env
  ```

<br>

### 2:.envと.gitignoreのファイルに取得したキー等入力
・.envファイルに記述(ファイルがない場合は手動で作成)
```ruby
GOOGLE_CLIENT_ID=自分のクライアントID
GOOGLE_CLIENT_SECRET=自分のクライアントシークレット
```

・.gitignoreの一番下の行に.envを記述
```ruby
～省略～

.env
```

**※.envだけだと、GitHubから丸見え状態となり悪意あるユーザが悪用してしまう可能性があります！！**

<br>

### 3:config/initializers/devise.rbで環境変数を設定する
```ruby
　config.google.key = ENV['GOOGLE_CLIENT_ID']
  config.google.secret = ENV['GOOGLE_CLIENT_SECRET']
  config.google.callback_url = "http://localhost:3000/oauth/callback?provider=google"
  config.google.user_info_mapping = { email: 'email', name: 'name' }
```
### コードの説明
- `ENV['GOOGLE_CLIENT_ID']`: 環境変数`GOOGLE_CLIENT_ID`に設定された値を取得している。これがGoogleのクライアントIDになる
- `ENV['GOOGLE_CLIENT_SECRET']`: 環境変数`GOOGLE_CLIENT_SECRET`に設定された値を取得して、Googleのクライアントシークレットになる
- **URLについて**：`config.google.callback_url`に設定されているURLは、OAuth 2.0のフローにおいてGoogleが認証後にリダイレクトする先のURLになります。このURLは、Google Cloud Consoleで設定した「承認済みのリダイレクトURI」と一致させる必要があります

<br>

## 続き+不足分の設定は以下参考

https://qiita.com/00000000/items/0c7dd9b523e960dae2a9

https://qiita.com/iloveomelette/items/b6e65caea88b6e86cfdd

https://zenn.dev/redheadchloe/articles/81dec8a2ba5e4a#google%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B

<br>


## ★おまけ：`ENV` と `credentials`どちらがいいのか？

`ENV` と `credentials` は、どちらもRailsアプリケーションで機密情報（APIキーやシークレットなど）を管理するために使用されますが、それぞれに特徴やメリット、デメリットがあります。どちらを使用するかは、プロジェクトの規模やチームの方針、デプロイ環境によって異なるそうです。

### 1：ENV 変数を使用する場合
#### 特徴
- **環境変数 (`ENV`)** は、システムレベルで設定される変数です。これにより、アプリケーションが動作する環境（開発、テスト、本番など）ごとに異なる設定を簡単に管理できます。

#### メリット
- **簡単に設定可能**: 環境変数は簡単に設定でき、ファイル変更を必要とせず、システムレベルで設定できるため、柔軟性があります。
- **デプロイ先の柔軟性**: HerokuなどのクラウドサービスやDockerコンテナなど、多くのデプロイ環境で環境変数の管理が推奨されています。
- **セキュリティ**: 機密情報がアプリケーションコードベースには含まれず、システムの外部に管理されます。

#### デメリット
- **可搬性の問題**: `.env`ファイルで管理する場合、ファイルが異なる環境間で同期されないことがあり、デプロイ時に環境変数が設定されていないと動作しないことがあります。
- **管理が煩雑**: 大規模なアプリケーションでは、多数の環境変数を管理するのが煩雑になることがあります。
- **セキュリティ**: `.env`ファイルを使う場合、誤ってこのファイルをバージョン管理に含めてしまうと、機密情報が漏洩するリスクがあります。

### 2：Railsの `credentials.yml.enc` を使用する場合
#### 特徴
- **Railsの `credentials.yml.enc`** は、機密情報を暗号化して保存するための仕組みです。デフォルトで`master.key`ファイルを使って暗号化・復号化を行います。

#### メリット
- **セキュリティ**: 機密情報が暗号化されているため、ソースコード管理システム（Gitなど）に含めても安全です。`master.key`があれば、どこでも復号化できます。
- **統合管理**: 環境ごとに機密情報を管理できるため、開発・テスト・本番環境で異なる設定を簡単に切り替えられます。
- **Railsに最適化**: Railsアプリケーションと統合されており、設定がシンプルでRailsの標準的な方法として推奨されます。

#### デメリット
- **セットアップが必要**: 初めて使う際に設定やファイルの扱いに慣れる必要があります。また、`master.key`の管理が適切に行われないと、他の開発者や環境での作業が困難になることがあります。
- **デプロイ環境の制約**: デプロイ先で`master.key`を適切に管理しないと、アプリケーションが正常に動作しなくなります。HerokuやCI/CDツールとの統合には工夫が必要です。
- **アクセス制限**: デプロイ後に特定の環境で一部の設定を変更したい場合に、再暗号化が必要となるためやや手間がかかります。

### 3：どちらを使用するのか？
- **小規模プロジェクトや迅速な開発環境**では、`ENV` 変数がおすすめされました。特にHerokuのようなPaaSを使用している場合や、Dockerコンテナを使って環境を分離している場合は、環境変数を使うのがシンプルで便利です。
- **中〜大規模なRailsプロジェクト**や、よりセキュリティが重要なプロジェクトでは、`credentials.yml.enc` をおすすめされました。これにより、ソースコードに機密情報が含まれることを防ぎつつ、環境ごとに設定を一元管理できます。

<br>

# さいごに
- **ENV**: 簡単で柔軟だが、管理が煩雑になる場合がある。PaaSやDocker環境での利用が一般的。
- **credentials.yml.enc**: セキュリティが強く、Railsプロジェクトに最適化されている。中〜大規模プロジェクトでの使用が推奨される。

いろんな機能を実装していく過程で「どれがいいんだろう？」問題が頻繁に発生。使いやすそうなものを選んだつもりがすごい時間かかったりしています。まぁ、どれ選んでも初めてなので結局のところ自分でさわってみないとわからない、という事をつよくかんじています。
私はセキュリティが強いとされているcredentialとsorceryの組み合わせで進めていますが、後からdeviceの方が便利だったかも、と思ったり。
次回挑戦してみたいです。

今回の記事が何か参考になれば幸いです。