【Rails4, OmniAuth】世界一丁寧なLINE LOGIN導入講座

# はじめに
みなさんこんにちは！
今回は、2015年の6月に公開されて、1年と少し経つ **LINE Login** をRailsで作ったwebアプリケーション内に組み込んでいこうと思います！

[LINE Login Platformの公開記事はこちら](http://developers.linecorp.com/blog/ja/?p=3542)

![LINE_login.png](https://qiita-image-store.s3.amazonaws.com/0/92468/7f0bddbc-3dae-a0dc-6535-86ffeab61dd4.png)
出典：[LINE developers](https://developers.line.me/)

#LINE Loginとは
LINE Loginとは皆さんが開発したwebアプリケーションのログイン時に、 **LINEのアカウントを使ってログインできるようにしてくれるプラットフォーム** です。
FacebookやGoogleのものは結構よく見ますね。ポケモンGOはGoogleのアカウントを使いますが、それのLINE版だと思っておいてください。

#導入方法
まずは、おおまかな導入方法を説明していきます。導入のステップは以下の4つです。
####① アカウント作成
####② CHANNEL作成
####③ OmniAuth設定
####④ コントローラー設定
####⑤ リダイレクトURLの設定
####⑥ モデル作成
####⑦ コントローラーとモデルの調整
####⑧ ビュー（おまけ）
####⑨ 本番環境で使う（おまけ）

#アカウント作成

まずは開発者用のアカウントの設定します。
※この時点で普通のLINEのアカウントを持っていない人は登録しましょう。

まずはこちらのLINE Business Centerで開発者用のアカウントを設定しましょう。

[LINE Business Center](https://business.line.me/ja/)

サイトにアクセスしたら、右上のログインボタンを押して、一般のLINEアカウントでアクセスします。そうしましたら、アカウント情報と企業情報を埋めます。

そうすると、開発者用のアカウントのマイページみたいなとこに飛ぶと思うので、このページの一番下にある、**ビジネスアカウントを作成する**というところをクリックしましょう。

![ビジネスアカウント作成___LINE_Business_Center.png](https://qiita-image-store.s3.amazonaws.com/0/92468/a33fc9af-fc84-4559-88b8-da77ed4a1cbb.png)

そうするとこんな感じの画面に飛びます。ビジネスアカウントは**サービスのアカウントという意味です**。
なので自分の名前ではなく、サービスおよびアプリケーションの名前と画像を登録しましょう。

これでアカウントのセッティングは終了です。

# CHANNEL作成
次はCHANNELを作成しましょう。

先ほどのビジネスアカウントの**完了する**というボタンを押すと、下記のようなページに飛びます。

![ビジネスアカウント詳細___LINE_Business_Center.png](https://qiita-image-store.s3.amazonaws.com/0/92468/e34f46a2-3b26-fef1-e28a-8b62b0d71d4e.png)
 
ここではそのアプリケーション内で使いたいAPIを選べるようですね。ここではもちろんLINE Loginを選びましょう。

そうすると。LINE Loginの説明ページみたいなとこに飛びます。ここははいはいと読み飛ばし、ページ最後の**利用開始**ボタンをクリックしてください。

次は下記のようなページに来るはずです。
![LINE_developers.png](https://qiita-image-store.s3.amazonaws.com/0/92468/ee7e94af-1712-bb4a-89c6-dc149b4e303c.png)

どうやらここから**CHANNEL**というものをつくっていくことのなりそうですね。
**CHANNELとはLINE LOGINのAPIにアプリケーションを識別させるための、設定みたいなもの**だと思っといてください。
ここでリダイレクトURLなどの設定をしますし、idなども発行されます。

ここは適当に、Description、App icon、Contact Mailing List Addressを埋めてください。
Application Typeのところは今回はwebアプリケーションなのでwebにチェックを入れて次に進みましょう。

これでひととおりのCHANNELの設定は終了です。リダイレクトURLも設定しなくてはいけないのですが、ここで一旦アプリケーションのファイルの方に戻りましょう。

#OmniAuth設定
ここからはアプリケーションの設定をしていきます。アプリケーションとLINE LoginのAPIを繋げるには **OmniAuth(オムニオース)認証**というプロトコルを使用します。
OmniAuthとはLINEだけでなく、**既に登録済みのSNSアカウントを利用して、あるサービスに登録する事ができる仕組みを提供しているプロトコル**です。

railsのgemが用意されているので、使っていきましょう。

```:Gemfile
gem 'omniauth-line'
```
を追加してbundle installします。

次はアプリケーションのアクセスキーとアクセスシークレットの設定をしていきます。

こんな感じで

```:config/settings.yml
production: &production
  line:
    key: hogehoge1234
    secret: hogesecret1234
development: &development
  line:
    key: hogehoge1234
    secret: hogesecret1234
test:
  <<: *development
```

設定します。このkeyとsecretの値はどこから引っ張ってくるのかと言うと先ほどのCHANNELの、、、

![LINE_developers1.png](https://qiita-image-store.s3.amazonaws.com/0/92468/61dcea0d-730e-361f-cf4a-3960f22aea83.png)

この部分から引っ張ってきます。access secretの値は右のshowボタンを押して表示しましょう。

**このファイルはくれぐれもpublicリポジトリとかにプッシュしないように**

そうしましたら次は、**deviseの設定ファイル**をいじっていきましょう。
※今回の記事ではログイン機能としてdeviseを使ってuserモデルを生成しているという前提で進んでいきます。

```:initializers/devise.rb
Devise.setup do |config|
  #中略
  OAUTH_CONFIG = YAML.load_file("#{Rails.root}/config/settings.yml")[Rails.env].symbolize_keys!
  config.omniauth :line, OAUTH_CONFIG[:line]['key'], OAUTH_CONFIG[:line]['secret']
end
```

```
config.omniauth :プロバイダー名, access_key, access_secret
```

の順番になっていることに注意してください。

#コントローラー設定
次はコントローラーを作成します。omniauth_callbacks_controllerをrailsコマンドで作成した後、

```:omniauth_callbacks_controller.rb
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def line; ; end
end
```

こんな感じでDevise::OmniauthCallbacksControllerを継承させて、あとはlineのアクションを定義しましょう。

ルーティングは、

```:routes.rb
devise_for :users, controllers: {
  omniauth_callbacks: "omniauth_callbacks"
}
```
上記の記述を追加します。

routingを確認すると、

```
user_line_omniauth_authorize  GET|POST /users/auth/line(.:format)           omniauth_callbacks#passthru
user_line_omniauth_callback   GET|POST /users/auth/line/callback(.:format)  omniauth_callbacks#line
```

こんな感じになっているかと思います。

実際のLINEログイン認証の流れは

users/auth/lineにリクエストを飛ばす→LINEのログイン画面に行く→emailアドレスとパスワードでログイン→認証許可を聞かれる→LINE Login APIが認証→users/auth/line/callback（リダイレクトURL）にリクエストが飛ぶ。

という流れになります。

ということは、users/auth/line/callbackをリダイレクトURLとして先ほど作ったCHANNELに登録しておけばよさそうですね。

#リダイレクトURLの設定

では、先ほどのCHANNELのページに移って、

![LINE_developers_url.png](https://qiita-image-store.s3.amazonaws.com/0/92468/e7e02510-30ea-9fc0-7cec-db347b12fa2a.png)

ここのTechnical configurationをクリックして、

![LINE_developers_url2.png](https://qiita-image-store.s3.amazonaws.com/0/92468/02874612-2b40-385e-8f4f-05a977f70ee0.png)

こんな感じで入力してみましょう。

...これでは実はできないんです。。。

LINE LoginのリダイレクトURLはまさかの、、

####**httpsじゃないと動かない**

んです。

もう一度言います。LINE LOGINは

####**httpsじゃないと動かない**のです。

httpsは簡単に言うとセキュリティの強化されたhttp通信ですね。最後のsはsecurityのｓだと思っておいてください。
要はセキュリティがしっかりしたサイトじゃないと使わせない、ということですね。高飛車ですね。

ではここで皆さんは、「development環境でhttps通信なんかできねーよオワタ」な人もいると思います。でも大丈夫。ちゃんと今回は良いものを用意しておきました。

今回はローカル環境で無理やりhttps通信をするために *ngrok* というものを使います。読み方は「エヌジーロック」が主流らしいですね。

ngrokとは、localhostで動いているサーバーを外部からアクセスできるようにリレーしてくれるツールです。平たくいうと、ローカルで動いていて本来そのパソコンからしかアクセスできないのに無理やり他のPCやスマホからアクセスできるようなURLを発行するツールみたいなものです。

[ngrokの詳しい説明はこちらから](https://liginc.co.jp/web/programming/156484)

ではさっそく使えるようにしていきましょう。

####インストール
```
brew install ngrok
```

####使い方
アプリのディレクトリで、、、

```
ngrok http 3000
```
※3000は適宜使用しているポート番号に置き換えてください。

そうするとこんな画面になると思います。

```
ngrok by @inconshreveable                                                                                           (Ctrl+C to quit)

Tunnel Status                 online
Update                        update available (version 2.1.14, Ctrl-U to update)
Version                       2.1.3
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://39dbff9b.ngrok.io -> localhost:3000
Forwarding                    https://39dbff9b.ngrok.io -> localhost:3000
```

これで外部からアクセスできるurlを発行しました。今回はhttpsを使いたいので、https://39dbff9b.ngrok.io
をコピペしておきます。ためしに手持ちのスマホでこのurlを開いてみましょう。ちゃんと開きます。あ、rails sは忘れずに。

あとcommand + cで終了するまではこのurlを使えますので、立ち上げっぱなしにしておいて、先程のTechnical configurationのところに、
https://39dbff9b.ngrok.io
を記入しましょう。

これでLINE Loginのapiにアクセスできるようになりました。次は取ってきたデータを保存するためのモデルを作っていきましょう。

#モデル作成
まずはモデルの設計から考えましょう。LINEやFacebookなど、それぞれのproviderに対し、1つ1つモデルを作ってもいいが、統一的に扱えるように、SocialProfileという名前のモデルを作ったほうがいいですね。後々違うSNSログインをつけるかもしれないので。

ここらへんの設計の考え方は、
awakiwaさんの [RailsでいろんなSNSとOAuth連携/ログインする方法](http://qiita.com/awakia/items/03dd68dea5f15dc46c15) の記事を大いに参考にさせて頂いております。これから作っていくコントローラーもそうですね。ありがとうございます。

詳しい説明は上記の記事に任せて、早速モデルとテーブルを作ります。以下のコマンドを入力してください。

```
rails g model SocialProfile user:references provider uid name nickname email url image_url description other:text credentials:text raw_info:text
```

その後、

```db/migrate/2016hogehogehoge_create_social_profiles.rb
add_index :social_profiles, [:provider, :uid], unique: true

```

を加えて、

```model/user.rb
class User < ActiveRecord::Base
  devise :omniauthable

  has_many :social_profiles, dependent: :destroy
  def social_profile(provider)
    social_profiles.select{ |sp| sp.provider == provider.to_s }.first
  end
end
```
こんな感じで書きます。

これでモデルの作成は終了です。

次はコントローラーとモデルを同時に中身を書いていきます。

#コントローラーとモデルの調整

ではまずコントローラーの中身を書いていきましょう。

```controllers/omniauth_callbacks_controller.rb
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def line; basic_action end
  
  private

  def basic_action
    @omniauth = request.env['omniauth.auth']
    if @omniauth.present?
      @profile = SocialProfile.where(provider: @omniauth['provider'], uid: @omniauth['uid']).first
      if @profile
        @profile.set_values(@omniauth)
        sign_in(:user, @profile.user)
      else
        @profile = SocialProfile.new(provider: @omniauth['provider'], uid: @omniauth['uid'])
        email = @omniauth['info']['email'] ? @omniauth['info']['email'] : Faker::Internet.email
        @profile.user = current_user || User.create!(email: email, name: @omniauth['info']['name'], password: Devise.friendly_token[0, 20])
        @profile.set_values(@omniauth)
        sign_in(:user, @profile.user)
        redirect_to edit_user_path(@profile.user.id) and return
      end
    end
    redirect_to root_path
  end
end
```

※良いコード募集中です。

LINE Loginは調べるとemail情報を取ってくることができないらしいので（もし取ってくるやり方知ってる方いたら教えてくださいm(__)m）、SNSのアカウント毎にユーザーを作るようにします。（ほんとはemail情報で参照して、ひとつのアカウントに複数のSNSアカウントを結び付けれればいいですね）

また、既にSocialProfilesのレコードがある場合はサインイン、ない場合はサインアップに飛べるように書いてあります。バリデーションの都合上、ランダムのemailを作成しておりますが、ユーザーのレコードを作成したときの条件分岐のところはユーザーの編集画面に飛ばすなどの工夫も必要ですね。


次はモデルの記述をしていきます。


```models/social_profile.rb
class SocialProfile < ActiveRecord::Base
  belongs_to :user

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

    self.access_token = credentials['refresh_token']
    self.access_secret = credentials['secret']
    self.credentials = credentials.to_json
    self.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
```

こんな形でset_valuesメソッドを定義させて、先程のコントローラー内で呼び出して上げれば、トークンなどの情報を保存することができますね。


あとは、もう

```views/devise/sessions/new.html.erb
<%= link_to "LINE Login", user_line_omniauth_authorize_path %>
```

こんな感じでどこかのビューでパスを呼び出してあげれば完成です。ためしてみましょう！！！！


#ビュー（おまけ）
参考までに、、、

```views/devise/sessions/new.html.erb
<li class="sns_login_btn" id="line_login">
  <%= link_to (user_line_omniauth_authorize_path) do %>
    <p class="sns_btn_inner">
      <span class="line-img">
        <%= image_tag( "content/line_64.png", :size => "20x20" ) %>
      </span>
      <span class="sns_msg">LINE</span>
    </p>
  <% end %>
</li>
```

```sns_login.css
.line-img{
  margin-right: 4px;
}

.line-img img{
  width: 17px;
  height: 17px;
  margin: 1px 0px 3px -3px;
}

#line_login{
  background: #00B900;
  color: #ffffff;
}


#line_login .sns_btn_inner{
  color: #ffffff;
}

.sns_btn_inner{
  font-size: 1.2rem;
  color: #FFFFFF;
  letter-spacing: 1px;
  line-height: 34px;
}
```

こんな感じで書きました。自分で作ったもののコピペなので、詳しい作り方は、 [こちら](https://developers.line.me/web-login/setting-up-login-button.) で確認お願いします。

![CafeMusicBgmStation2.png](https://qiita-image-store.s3.amazonaws.com/0/92468/bb1f8b02-0809-5bc5-5786-f9a4b3437e42.png)


#本番環境で使う（おまけ）
本番環境で使う場合は、LINE Developerの申請を通す必要があります。
まずはチャンネルの管理画面まで行って、EDITをクリックします。

![LINE_developers_edit.png](https://qiita-image-store.s3.amazonaws.com/0/92468/e6661840-2953-ff9e-d575-5a1122ba394b.png)

編集画面でStatusのチェックをpublishedにします。

![LINE_developers_status.png](https://qiita-image-store.s3.amazonaws.com/0/92468/63ba5f3f-9d05-d01f-a6bc-ff7b0cbcd865.png)

そうすると申請書を出せ、みたいな流れになるので、

ページ下部のSUBMITをクリック。

![LINE_developers_submit.png](https://qiita-image-store.s3.amazonaws.com/0/92468/c3e23cdb-4829-35e8-14f3-33ab3facc8f8.png)

下記のようにポップアップで申請画面が出るので、以下のようにしてSUBMITを押してください。そうすると申請ができて、数日以内に結果が通ります。

![LINE_developers_submission.png](https://qiita-image-store.s3.amazonaws.com/0/92468/7574c961-8170-07e3-4b68-cca586aafff6.png)

なかなか申請が通らないことが多く、通らない理由は以下のだいたい以下の4つです。

####①ログインボタンが規約通り作られていない。
####②チャンネル管理画面でアプリの画像が登録されていない。
####③faviconが登録されていない。
####④iPhone用のアイコンが登録されていない。

ですのでちょっと色々他の記事見ながら頑張ってみてください！
わからない場合は申請画面のCommentの欄を使って質問すると返してくれます。

**あれ本番環境でhttpsどうやって導入するの？？** って方は、
[GlobalSign](https://jp.globalsign.com/) とか対応が親切だったので使ってみてください。

# お疲れ様でした！
どうだったでしょうか？？
この記事によって、皆さんの作った自慢のサービスがLINEアカウントでログインできるようになれば幸いです。（LINE LOGIN関連の記事は絶望的に少ないので、、）

ミス等ありましたら、気軽にコメントくださると幸いです！