2018年12月7日

プログラミング

sorceryで実装するLINEログイン

目次

  1. はじめに
  2. devise? sorcery?
  3. モンキーパッチを当てる
  4. LINEログインのための設定
  5. まとめ

はじめに

新しい技術にチャレンジし続けるeishisのアドベントカレンダーDay7です!

昨日はキーボードで画面が隠れる場合の対処法(React Native)についての記事でした。

【React Native】キーボードで画面が隠れる場合の対処法

今日は gem sorcery にモンキーパッチを当ててLINEログインを実装した方法をお伝えします!

sorcery のGithubリポジトリ

今回使用する環境

  • Ruby: 2.5.0
  • Ruby on Rails: 5.2.1
  • sorcery: 0.12.0(インストールまで終わっている状態)
  • LINEログイン: 2.1

devise? sorcery?

認証系の gem でよく使われる devise と sorcery の違いをまとめてみました。

deviseの特徴

コマンド1つでviewまで作成してくれる!
gem omniauth-line を併用すればLINEログインにも対応!
カスタマイズしようとするとつらい…

sorceryの特徴

便利なメソッドを提供してくれるイメージ
カスタマイズしやすい
LINEログインには不対応(facebook, twitterなどは対応)

どちらを使う?

devise は view まで用意してくれとても便利です。しかし、実際にRailsアプリを開発しているとそのままで使える事なく、ほぼカスタマイズ必須。以前 devise のカスタマイズでつらい思いをした事もあり、個人的には sorcery が好きです。

でもLINEログインに対応していない!
ということで、 sorcery にモンキーパッチを当ててLINEログインを実装することにしました。

モンキーパッチを当てる

ファイルの置き場所などはこちらを参考にしました。

クックパッド開発者ブログ:Ruby on Rails アプリケーションにおけるモンキーパッチの当て方

また、sorcery を LINEログイン に対応させるためのPRがあります(2018.11現在マージされておらず…)
モンキーパッチの内容についてはこちらのPRを基に、LINEログインのバージョンアップに伴い仕様が変更していた部分を修正しました。
sorcery / Support the LINE login auth(PR)

下準備

初期化時に lib/monkey_patches 以下を読み込むように

config/initializers/000_monkey_patches.rb

Dir[Rails.root.join('lib/monkey_patches/**/*.rb')].sort.each do |file|
  require file
end

モンキーパッチ

lib/monkey_patches/sorcery_ext.rb

module Sorcery
  module Controller
    module Submodules
      # This submodule helps you login users from external auth providers such as Twitter.
      # This is the controller part which handles the http requests and tokens passed between the app and the @provider.
      module External
        def self.included(base)
          base.send(:include, InstanceMethods)

          require 'sorcery/providers/base'
          require 'sorcery/providers/facebook'
          require 'sorcery/providers/twitter'
          require 'sorcery/providers/vk'
          require 'sorcery/providers/linkedin'
          require 'sorcery/providers/liveid'
          require 'sorcery/providers/xing'
          require 'sorcery/providers/github'
          require 'sorcery/providers/heroku'
          require 'sorcery/providers/google'
          require 'sorcery/providers/jira'
          require 'sorcery/providers/salesforce'
          require 'sorcery/providers/paypal'
          require 'sorcery/providers/slack'
          require 'sorcery/providers/wechat'
          require 'sorcery/providers/microsoft'
          require './lib/monkey_patches/line'

          Config.module_eval do
            class << self
              attr_reader :external_providers
              attr_accessor :ca_file

              def external_providers=(providers)
                @external_providers = providers

                providers.each do |name|
                  class_eval <<-E
                    def self.#{name}
                      @#{name} ||= Sorcery::Providers.const_get('#{name}'.to_s.capitalize).new
                    end
                  E
                end
              end

              def merge_external_defaults!
                @defaults.merge!(:@external_providers => [],
                                 :@ca_file => File.join(File.expand_path(File.dirname(__FILE__)), '../../protocols/certs/ca-bundle.crt'))
              end
            end
            merge_external_defaults!
          end
        end
      end
    end
  end
end

lib/monkey_patches/line.rb

require 'sorcery/providers/base'

module Sorcery
  module Providers
    # This class adds support for OAuth with line.com.
    #
    #   config.line.key = <key>
    #   config.line.secret = <secret>
    #   ...
    #
    class Line < Base
      include Protocols::Oauth2

       attr_accessor :token_url, :user_info_path, :auth_path, :scope

       def initialize
        super

        @site           = 'https://access.line.me'
        @user_info_path = 'https://api.line.me/v2/profile'
        @token_url      = 'https://api.line.me/oauth2/v2.1/token'
        @auth_path      = 'oauth2/v2.1/authorize'
      end

       def get_user_hash(access_token)
        response = access_token.get(user_info_path)
        auth_hash(access_token).tap do |h|
          h[:user_info] = JSON.parse(response.body)
          h[:uid] = h[:user_info]['userId'].to_s
        end
      end

      # calculates and returns the url to which the user should be redirected,
      # to get authenticated at the external provider's site.
      def login_url(_params, _session)
        @state = SecureRandom.hex(16)
        authorize_url(authorize_url: auth_path)
      end
      # tries to login the user from access token
      def process_callback(params, _session)
        args = {}.tap do |a|
          a[:code] = params[:code] if params[:code]
        end
         get_access_token(args, token_url: token_url, token_method: :post)
      end
    end
  end
end

LINEログインのための設定

基本的には sorcery の wiki にある通りに進めていきます
sorcery / External

(LINE developers の登録などはここでは省略)

initializer/sorcery.rb

LINE関連のパラメーターがないのでこちらを追加
config/initializers/sorcery.rb

Rails.application.config.sorcery.submodules = [:external, ...]

Rails.application.config.sorcery.configure do |config|
  ...
  config.external_providers = [:line]
  ...
  config.line.key = ENV["LINE_KEY"]
  config.line.secret = ENV["LINE_SECRET"]
  config.line.callback_url = ENV["LINE_CALLBACK"]
  config.line.scope = 'profile'
  ...

あとは dotenv などを利用して環境変数を指定すればLINEログインを使えるようになります!

まとめ

以上が sorcery でLINEログインを実装する方法です。
sorcery もLINEログインに対応してもらえるとありがたいのですが、海外でのLINEの認知度が低いこともありなかなか進んでいないようです。
LINEログインが必要になった際は使ってみてください!

0

0

AUTHOR

はらた

はらた エンジニア

サーバーサイドエンジニア Ruby on Railsを使った開発を行なっています

アプリでもっと便利に!気になる記事をチェック!

記事のお気に入り登録やランキングが表示される昨日に対応!毎日の情報収集や調べ物にもっと身近なメディアになりました。

eishisでは一緒に働く仲間を募集しています

正社員や業務委託、アルバイトやインターンなど雇用形態にこだわらず、
ベテランの方から業界未経験の方まで様々なかたのお力をお借りしたいと考えております。

話を聞いてみたい

運営メンバー

eishis

Eishi Saito 総務

SIerやスタートアップ、フリーランスを経て2016年11月にeishis, Inc.を設立。 マーケター・ディレクター・エンジニアなど何でも屋。 COBOLからReactまで色んなことやります。

sasakki デザイナー

アメリカの大学を卒業後、日本、シンガポールでデザイナーとして活動。

しまだ

しまだ デザイナー

WebAR/VRのデザインと3DCG制作がメインです。 肩書きは「アニメ案件に関わりたいデザイナー」。

Miu マーケター

ドイツでWEBマーケティングしています。

しんのき エンジニア

新しい技術が好きなWebエンジニアです。 元々インフラやPHPをやっていたのですが、最近はReact NativeとFirebaseを使って頑張ってます。

yamakawa

やまかわたかし デザイナー

フロントエンドデザイナー。デザイン・HTML/CSSマークアップ・JSアニメーション実装を担当しています。

furuya エンジニア

サーバーサイド、フロントエンド、Unityと色々手を出してる雑食系エンジニア。ReactNativeが最近のマイブーム。

Sayaka Osanai デザイナー

Sketchだいすきプロダクトデザイナー。シンプルだけどちょっとかわいいデザインが得意。 好きな食べものは生ハムとお寿司とカレーです。

はらた

はらた エンジニア

サーバーサイドエンジニア Ruby on Railsを使った開発を行なっています

うえまつゆい エンジニア

サーバーサイドエンジニアからフロントエンドエンジニアになりました。主にReact Nativeでのアプリ開発をしています。

CONTACT PAGE TOP