ソーシャルログインサービス（Line）

-Ruby on Railsのバージョン:7.2.1
-Rubyのバージョン:3.3.5

ポートフォリオにソーシャルログインサービスを実装しようと思い、一旦Lineのソーシャルログインサービス機能の実装をしました。

下記Qiita記事を参考にしながら実装したらそこまで躓かずにできました。

 https://qiita.com/s10aim_tana/items/2d174d4e31e4041700ee#comments
 

基本的には大丈夫だったんですが、数箇所で躓いたところがあり、そこについてまとめていきます。また、個人的にここの理解を進めずに進めたらだめだなと思ったところもまとめていきます。
※上記URLの内容を基準に話を進めていきます。

## DeviseとLINEログインの設定
```user.rb
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable,
         :omniauthable, omniauth_providers: %i[line] # この1行を追加
end
```

4-3.DeviseとLINEログインの設定部分で
:omniauthable, omniauth_providers: %i[line] # この1行を追加、とある箇所なのですが
なぜ追加するのか？
↓
①:omniauthable
役割：OmniAuthを使った外部認証（LINEやGoogleなど）の機能を有効にする。

②omniauth_providers: %i[line]
役割：使用するOmniAuthプロバイダ（LINEなど）を指定します。
%i[line] は、使用する認証プロバイダーを「LINE」に設定していることを意味します。
複数のプロバイダーを利用する場合、以下のように記述します：
```ruby
omniauth_providers: %i[line x instagram]
```

## ルーティングの設定
4-5.ルーティングの設定より、
下記のようなルーティングは初めて見たので調べてみました。
```routes.rb
devise_for :users, controllers: {
  omniauth_callbacks: "omniauth_callbacks"
}
```
①controllers: { omniauth_callbacks: "omniauth_callbacks" }
役割：Deviseが処理する外部認証（OmniAuth）のコールバックを処理するためのカスタムコントローラを指定する。
OmniAuthでは、認証後にサービス（例: LINE）からアプリケーションにリダイレクトされます。このリダイレクト先を「コールバック」と呼びます。
コールバック用のルートをこの設定で有効にします。
認証が成功または失敗した後の処理を、このカスタムコントローラで定義します。

**カスタムコントローラを指定する理由**
OmniAuthの認証プロバイダごとに異なる処理が必要になるため、OmniauthCallbacksController を定義して柔軟に対応する。

## Userモデルの編集
下記に記載されているコードの意味について特に説明がなかったので自分なりにまとめていきます。間違っていたらご指摘をお願いします。
```user.rb
class User < ApplicationRecord
~
# 以下を追加
  def social_profile(provider)
    social_profiles.select { |sp| sp.provider == provider.to_s }.first
  end

  def set_values(omniauth)
    return if provider.to_s != omniauth["provider"].to_s || uid != omniauth["uid"]
    credentials = omniauth["credentials"]
    info = omniauth["info"]

    access_token = credentials["refresh_token"]
    access_secret = credentials["secret"]
    credentials = credentials.to_json
    name = info["name"]
    # self.set_values_by_raw_info(omniauth['extra']['raw_info'])
  end

  def set_values_by_raw_info(raw_info)
    self.raw_info = raw_info.to_json
    self.save!
  end
  # 以上を追加
end
```
```
def social_profile(provider)
    social_profiles.select { |sp| sp.provider == provider.to_s }.first
end
```
social_profilesとはおそらくテーブルの名前で、そこから{ |sp| sp.provider == provider.to_s }の条件()に一致したものをselectで返し、その中で最初の要素を返すというメソッドだと思われます。
ただこのメソッド使われてないみたいなんですよね、
何で記載してんだろ

```
def set_values(omniauth)
    return if provider.to_s != omniauth["provider"].to_s || uid != omniauth["uid"]
    credentials = omniauth["credentials"]
    info = omniauth["info"]

    access_token = credentials["refresh_token"]
    access_secret = credentials["secret"]
    credentials = credentials.to_json
    name = info["name"]
    # self.set_values_by_raw_info(omniauth['extra']['raw_info'])
end
```
return if 条件式
「条件式」が true の場合、return を実行してメソッドの処理を終了します。
「条件式」が false の場合、return を実行せずに次の処理に進みます。

**return if provider.to_s != omniauth["provider"].to_s || uid != omniauth["uid"]**
provider（文字列化したもの）とomniauth["provider"].to_s（外部認証によって取得したprovider）が同じ（true）でなければ処理を終了し、同じであれば（false）次の条件に進む。
uidが外部機能によって取得したuidと同じでなければ処理を終了する。
つまりこの部分は、言い換えると
**外部認証で取得した provider と uid が現在の値と一致しない場合に処理を終了する**、です。
```    
def fake_email(uid, provider)
    "#{auth.uid}-#{auth.provider}@example.com"
end
```
ダミーメールを作成するメソッド
{auth.uid}は外部認証から取得したuid、{auth.provider}は外部認証から取得したprovider
uidが12345、auth.providerがlineだった場合
12345-line@example.comとなる

ただこのメソッドも使用されていないみたい、
## ngrok
5-2.ngrokより、
最終更新日が2022年ということもありngrokのインストール方法に関連する内容が結構変わっておりました。そのため下記記事を参考にしながらngrokのインストールから設定までを行いました。

https://qiita.com/miriwo/items/8c1e6550a5ab279d60b5

最初の記事とこちらの記事を見ながらであれば設定を進めることができました。ただ、下記については抜けがあったため補足として記載します。

**4-3.DeviseとLINEログインの設定**のところで下記のようなコードがありました。
```devise.rb
config.omniauth :line, ENV['LINE_KEY'], ENV['LINE_SECRET']
```
外部認証が成功した場合、遷移してほしいURLを設定するのですが、そのURLのことを**コールバックURL**と言います。
このコールバックURLをここのコードに記載しないと下記スクショのようなエラーが起こります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931580/dd4c4d3e-0316-5b6e-f68a-ce27a1f245eb.png)

```devise.rb
config.omniauth :line, ENV['LINE_KEY'], ENV['LINE_SECRET'], callback_url: "https://xxxxxxx.ngrok-free.app"
```
ngrok
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931580/7096fe48-7b6d-4f70-f543-a01f5da2c80b.png)

callback_urlにはngrokのスクショのForwardingの行の"https://~~~app"を記載しよう。
Line DevelopersのコールバックURLもここの値が入ります。


以上になります。
おそらくまだ気にしないといけない部分はあると思いますが、一旦はこれでソーシャルログイン（Line）機能の実装はできるのでないかと思われます。

ご意見などありましたらコメントいただけると幸いです。