Hinode LaboBlog技術LINEログインv1(mid)とv2(uid)でユーザーIDが異なるため、データをマイグレーションする方法

LINEログインv1(mid)とv2(uid)でユーザーIDが異なるため、データをマイグレーションする方法

要件

iOS, Android用アプリのAPIと、Webのサーバーサイドの実装がそれぞれ異なるソースコードで管理されているプロジェクトに参画した際、両者でLINEログインのバージョンが異なり、
「Webではログインできるけど、アプリではログインできません」
「アプリではログインできるけど、Webではログインできません」
といったクレームが多発し、混乱したことがありました。
LINEログインv2以降では、ユーザーはMIDではなくユーザーIDで識別されます。
LINEログインv1を実装済みのアプリをv2以降へ移行する場合、以下の手順に従って複数のMIDを一括で変換します。

実装解説(Controller)

(1) v2のアクセストークンを取得する
(2) midsをstringで用意し、LINE APIのmigration用endpointにrequestする

(3) midと対になるuidが1行ずつ返却されるので、splitして変換処理を行う


require 'dotenv'
Dotenv.load

class LineMidToUid

  def initialize
    fetch_access_token
  end

  def convert
    line_user_mids = ''
    User.where(provider: 'line').pluck(:mid)&.each do |mid|
      line_user_mids += <<~EOS
        #{mid}
      EOS
    end

    Rails.logger.info line_user_mids.bytesize

    migration_bulk(line_user_mids)

    User.transaction do
      @ids.each_line do |line|
        ids = line.split(" ")
        Rails.logger.info "converting...LINE mid to uid"
        p ids
        next if ids.size < 2
        p ids[0]
        p ids[1]
        user = User.find_by(mid: ids[0])
        user.uid = ids[1]
        user.save!(validate: false)
        Rails.logger.info "++ end ++"
      end
    end
  end

  private

  def fetch_access_token
    query = {
      grant_type: 'client_credentials',
      client_id: ENV['LINE_CHANNEL_ID'],
      client_secret: ENV['LINE_CHANNEL_SECRET'],
    }

    RestClient.post(
      'https://api.line.me/v2/oauth/accessToken',
      query,
      {
        "Content-Type": "application/x-www-form-urlencoded"
      },
    ) { |response, request, result, &block|
      res = JSON.parse(response)
      Rails.logger.info res
      @access_token = res['access_token']
    }
  end

  def migration_bulk(line_user_mids)
    RestClient.post(
      'https://api.line.me/v2/bot/dedisco/migration/userId/getbulk',
      line_user_mids,
      {
        "Authorization": "Bearer #{@access_token}",
        "Content-Type": "text/plain"
      },
    ) { |response, request, result, &block|
      Rails.logger.info response
      @ids = response.body
    }
  end
end

rake taskの追加
以下のファイルを/lib/tasks/line_mid_to_uid.rakeに作成し、bundle exec rake line_mid_to_uidを一度だけ実行する。


require 'line_mid_to_uid'

  desc 'line_mid_to_uid (only one time)'

  task line_mid_to_uid: :environment do
    obj = LineMidToUid.new
    obj.convert
  end

まとめ

・MID変換エンドポイントにアクセスするためのアクセストークンを取得する。
・前のステップで取得したアクセストークンを使ってMIDをユーザーIDに変換する。
至ってシンプルですが、急にユーザーからクレームが来ると焦りますよね。
LINEログインを実装する際は、versionをよく確認して実装するようにしましょう。