【Rails】SNS認証の登録手順(Twitter、Facebook、google)

- deviseを用いた、Twitter、Facebook、googleでのログイン認証を目的にした、アカウント登録〜Key取得までの備忘録です。
- [Key取得後〜アプリ側実装の備忘録はこっち](https://qiita.com/manbolila/items/48d361fd5968179918c3)







## Google API の登録
[Google Cloud Platform](https://console.developers.google.com/project)にログインし、プロジェクトを作成。

今回は、「ユーザー認証」のみなので、使わないAPIは無効にしとく（ 最低限の Google+ API だけ有効）。
![Alt text](https://gyazo.com/9a0e8c101c9457ba043932024c58fbcb/raw)
![Alt text](https://gyazo.com/beec41525e971fec0e32ad0465f26bf3/raw)
OAuth 同意画面で設定後、認証情報をクリック（OAuth 同意しないと、認証情報を追加できない。同意画面にアプリ名を入力し、保存)。
![Alt text](https://gyazo.com/515b1d236ce26d4c9d3ef3d4c77ba1df/raw)
**・** アプリケーションの種類: ウェブ アプリケーション、アプリ名を入力、承認済みのリダイレクトURI(コールバック のURI)を設定する。
(例：ローカルの場合) 
http://localhost:3000/users/auth/google_oauth2/callback
http://localhost:3000/users/auth/google/callback
**・** KeyとSecretが自動生成されるので、メモっとく。
![Alt text](https://gyazo.com/f46c162cacee0100cf9abdfa9ab32ede/raw)

















## Facebook API の登録
[Facebook developers](https://developers.facebook.com/)で、ログインし、アプリを作成すると、マイアプリ(KeyとSecret)が自動生成される。
![Alt text](https://gyazo.com/c204386ab8353de662f0031f67f8a8f1/raw)
![Alt text](https://gyazo.com/de3be5301e690d881b39d80d7861ef5e/raw)
ローカルなら、 http://localhost:3000 でok。
![Alt text](https://gyazo.com/905d52610ee6c52759518a256bf87ca2/raw)
ダッシュボードに行く。
![Alt text](https://gyazo.com/28c668c9ec882932261f64263c84c459/raw)
App IDとSECRETをメモっとく。
![Alt text](https://gyazo.com/cdd4f246f0360eeca5768a294e88b92a/raw)
コールバック用のURIを追記。ローカルなら、 https://localhost:3000/users/auth/facebook/callback。
![Alt text](https://gyazo.com/afa4d25ef1c2f595ad24998a9616922a/raw)











## Twitter API の登録
アカウント作成 → API登録申請 → 確認メール → 作成するアプリに関する設定

### API 登録申請
#### Twitter Developer のアカウント作成
[Twitter Developer](https://developer.twitter.com/)にログイン。
![Alt text](https://gyazo.com/3242e53bcc6be4e3507c273a2f67a75c/raw)
![Alt text](https://gyazo.com/05481afb931413f6594d4192d857afa5/raw)
![Alt text](https://gyazo.com/fd7214c7addb13530d1e163869b9ff17/raw)
![Alt text](https://gyazo.com/e4caf1d8b917fcebb0b629b6d5fddc7d/raw)
携帯番号を入力して、 Next。認証コードを入力。
<img src="https://gyazo.com/53a0547d542241c92f7e33cd7e3fdcef/raw" width=50%>
![Alt text](https://gyazo.com/05e3c7d6727afbe4e3e6ae8571e15ae6/raw)
![Alt text](https://gyazo.com/619807ec723c296515817db8999018cb/raw)
![Alt text](https://gyazo.com/2a43fe9a6e8e2bac51e3fa0c67bfd9c2/raw)
内容を確認し、 Looks Good！ 次に、利用規約に同意のチェックを入れ、 Submit Application をクリック。
<img src="https://gyazo.com/f0e9e0d39f3badbe8c5b5c25647dcd9b/raw" width=50%><img src="https://gyazo.com/47850dd090029b217f9eadfd91cf04cc/raw" width=50%>
完了画面が表示され、メールが届くので、 Confirm your email をクリックで完了。
<img src="https://gyazo.com/42564482cbf516e34c20ace1d9e7d5ca/raw" width=50%><img src="https://gyazo.com/8024ac5af71994e72dce46982ad14468/raw" width=50%>



#### Twitterの API_KEY、 API_SECRET取得
[developer account](https://developer.twitter.com/en/account/get-started)にアクセスし、アプリ名を入力（一意性）。作成された、API_KEYとAPI_SECRETをコピーしとく。
<img src="https://gyazo.com/6904797fd444f587d9cc118120632f49/raw" width=50%><img src="https://gyazo.com/39d1f2cb2f93c5bf78ad3a50d7b75b66/raw" width=50%>
コールバックurlの設定。
<img src="https://gyazo.com/666cca39bbe5d5c873f4ef05abde8a7b/raw" width=50%><img src="https://gyazo.com/5f4d0a66d85803b2a1268936c505c852/raw" width=50%>
・ permission： read only
・ Request email addresses from usersにチェック
・ Enable Sign in with Twitter(Twitter認証を使用するか): ONにする
・ Website URL(自分のwebサービスのURL)
・ callback urls(Twitter認証後に遷移するURL)： ローカル/本番環境など、複数設定が可能。
(例)
http://localhost:3000/users/auth/twitter/callback (ルーティングの確認)
http://localhost:3000/users/omniauth_callbacks (コールバック用コントローラのURL、認証後の遷移)
・ privacy policy, terms of serviceも何でもいいので埋める。
<img src="https://gyazo.com/134e4b2d1b316adea46f2345f63aa445/raw" width=50%><img src="https://gyazo.com/52f081ee9d63185a7e08a0e4f956b375/raw" width=50%>















## アプリ側の設定：gemとテーブルの準備

```rb:Gemfile
gem 'omniauth-facebook'                  # Facebook認証
gem 'omniauth-twitter'                   # Twitter認証
gem 'omniauth-google-oauth2'             # Google認証
gem 'omniauth-github'                    # GitHub認証
gem 'dotenv-rails'                       # 環境変数の管理
# gem 'omniauth-rails_csrf_protection'   # 脆弱性の対策用。。入れたら認証エラー！になったので、アンインストール。

# ターミナルでインストール
% bundle install --path vendor/bundle
```

### ■ 登録ボタンをクリック → ユーザー登録完了する仕様 の場合
- 必要なカラム(provider、uidカラム)をuserテーブルに追加。

```:ターミナル
% rails g migration AddOmniauthToUsers provider:string uid:string
% rails db:migrate
```
```rb:Userモデルomniauthのためのオプションを追加
devise :database_authenticatable, :registerable,
       :recoverable, :rememberable, :validatable, :omniauthable, omniauth_providers: [:twitter, :facebook, :google_oauth2]
```


### ■ 登録ボタンをクリック → SMS認証 → 名前、メールアドレス自動入力 + PW入力欄が非表示(入力省略) → それ以外の情報を入力し、ユーザー登録完了 の場合
- **SNS認証とユーザー登録のタイミングが異なる**仕様の場合、SNS認証時は、Usersテーブルのレコードを作成しないので、別テーブル管理が良い。
- SNS認証時の情報保存用にSnsモデルを作成(uid、providerカラム)。Userモデルとアソシエーションで、外部キーとしてuser_idを追加。

```:ターミナル
% rails g model sns provider:string uid:string user:references
% rails db:migrate
```
```rb:userモデルにomniauthのためのオプション、アソシエーションを追加
devise :database_authenticatable, :registerable,
       :recoverable, :rememberable, :validatable, :omniauthable, omniauth_providers: [:twitter, :facebook, :google_oauth2]

has_many :sns
```
```rb:snsモデルにも、アソシエーション
belongs_to :user, optional: true    # 外部キー(user_id)のnilを許可
# 初めて、SNS認証でユーザー登録する時は、まだuser_idは存在しないため、ユーザー情報が見つからないと言われる(エラー)
```




### 公開しない情報をpushしないにように設定する
- API_KEYとAPI_SECRET を環境変数にする（gem(dotenv-rails)）。
- `.env` ファイルを「Gemfile」と同じ階層に手動で作成し、`.gitignore`に追加する。

```:.gitignore
/.env
```
- `.env` ファイルに、上でメモったKeyを環境変数に設定。

```:.env
TWITTER_API_KEY = 'API key を記述'
TWITTER_API_SECRET = 'API secret key を記述'

FACEBOOK_KEY = 'API key を記述'
FACEBOOK_SECRET = 'API secret key を記述'

GOOGLE_CLIENT_ID = 'API key を記述'
GOOGLE_CLIENT_SECRET = 'API secret key を記述'
```

**※** `$ vim ~/.bash_profile` で設定してもok(変更後に、 `$ source ~/.bash_profile` を実行を忘れずに )！！
**※** `export` : 環境変数設定のコマンド
**※** `.bash_profile` : ログイン時に読まれる設定ファイル。

```rb:~/.bash_profile
# i (挿入モード)で編集
# = の前後に空白を入れるとエラーになるので注意!!
export TWITTER_CLIENT_ID='API key を記述'
export TWITTER_CLIENT_SECRET='API secret key を記述'

export FACEBOOK_CLIENT_ID='API key を記述'
export FACEBOOK_CLIENT_SECRET='API secret key を記述'

export GOOGLE_CLIENT_ID='API key を記述'
export GOOGLE_CLIENT_SECRET='API secret key を記述'
# escキーで編集終了し、:wq (保存して終了)。
```





- 環境変数を使って、omniauth用を設定。

```rb:config/initializers/devise.rb
  config.omniauth :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET']
  config.omniauth :twitter, ENV['TWITTER_API_KEY'], ENV['TWITTER_API_SECRET']
  config.omniauth :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET']
```

## ルーティングの設定
- 今回は、deviseが提供するアクションの内容をカスタマイズしたいので、deviseクラスを継承するコントローラーが生成し、アクションをオーバーライドする(controllers/usersにdeviseクラスを継承)。そのため、ルーティング変更。
  - SNS認証でのユーザー登録時だけ、PW入力を不要にしたい。

```rb:routes.rb
devise_for :users, controllers: {
  omniauth_callbacks: 'users/omniauth_callbacks',
  registrations: 'users/registrations'
}
# rails routes で確認(omniauth_callbackコントローラーを介し、APIにリクエストを送る)。
```

ここで、環境変数を設定できてるか確認しとく。

```rb:ターミナル
% rails c
irb(main):001:0> ENV['FACEBOOK_KEY']  => "1111111111111"
irb(main):002:0> ENV['FACEBOOK_SECRET']  => "1a1a1a1a1a1a1"

irb(main):001:0> ENV['TWITTER_API_KEY']  => "1111111111111"
irb(main):002:0> ENV['TWITTER_API_SECRET']  => "1a1a1a1a1a1a1"

irb(main):003:0> ENV['GOOGLE_CLIENT_ID']  => "~~~~~~googleusercontent.com"  # 末尾を確認
irb(main):004:0> ENV['GOOGLE_CLIENT_SECRET']  => "1a1a1a1aa1_1a1a1_1a"
```

後は、モデルとコントローラーでメソッドを記述し、呼び出せるようにする。