liff.getIDToken()で取得したIDTokenを使ってRailsサーバーでユーザー情報を取得するメモ
LIFF用の初期設定
application.html.slimにLIFF用のCDNを埋めると勝手に最新版を使ってくれるらしくさらに設定がこれだけで済むから楽。
doctype html html head title | LiffIdTokenSample script charset="utf-8" src="https://static.line-scdn.net/liff/edge/2/sdk.js" = csrf_meta_tags = csp_meta_tag = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' = javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' body = yield
config/environments/developmentのhosts設定を無くしてます。理由は開発環境にngrokを使っててurlが結構頻繁に変わるからです。
Rails.application.configure do config.hosts.clear end
View(楽したいからslimを使ってます)
h1 |Profile button#getProfile |getProfile p#iss |iss: p#sub |sub: P#aud |aud: p#exp |exp: p#iat |iat: p#authTime |auth_time: p#nonce |nonce: p#amr |amr: p#name |name: p#picture |picture: p#email |email:
JavaScript
window.onload = function(){ const token = document.querySelector('meta[name="csrf-token"]').getAttribute('content'); const getProfileButton = document.querySelector("#getProfile") const iss_field = document.querySelector("#iss") const sub_field = document.querySelector("#sub") const aud_field = document.querySelector("#aud") const exp_field = document.querySelector("#exp") const iat_field = document.querySelector("#iat") const authTime_field = document.querySelector("#authTime") const nonce_field = document.querySelector("#nonce") const amr_field = document.querySelector("#amr") const name_field = document.querySelector("#name") const picture_field = document.querySelector("#picture") const email_field = document.querySelector("#email") liff.init({ liffId: "自分のliffIDを入れてね" }) .then(() => { if (!liff.isLoggedIn()) { liff.login(); } }) .catch((err) => { console.log(err.code, err.message); }); getProfileButton.addEventListener('click', () => { let idToken = liff.getIDToken() let body =`idToken=${idToken}` let request = new Request('/users', { headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8', 'X-CSRF-Token': token }, method: 'POST', body: body }); fetch(request) .then(response => response.json()) .then(data => { console.log(data) iss_field.append(data.iss) sub_field.append(data.sub) aud_field.append(data.aud) exp_field.append(data.exp) iat_field.append(data.iat) authTime_field.append(data.auth_time) nonce_field.append(data.nonce) amr_field.append(data.amr) name_field.append(data.name) picture_field.append(data.picture) email_field.append(data.email) }) }) }
なんかごちゃごちゃ書いてありますが大方表示用のやつなので今回主に大事なとこはこれだけです。
let idToken = liff.getIDToken() let body =`idToken=${idToken}` let request = new Request('/users', { headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8', 'X-CSRF-Token': token }, method: 'POST', body: body }); fetch(request)
liff.getIDToken()
で取得したIDTokenをfetch
メソッドを使ってRailsに渡してます。
Controller
class UsersController < ApplicationController require 'net/http' require 'uri' def create idToken = params[:idToken] channelId = '自分のチャンネルIDを入れてね' res = Net::HTTP.post_form(URI.parse('https://api.line.me/oauth2/v2.1/verify'), {'id_token'=>idToken, 'client_id'=>channelId}) render :json => res.body end end
JSからfetchで渡したIDTokenをLINEにPOST通信でHTTPリクエストを投げてユーザー情報をもらって表示のためにフロントに返します。
IDTokenを検証するためのHTTPリクエスト
LINEにIDTokenを投げる時のHTTPリクエストのbody
にはid_token
とclient_id
(Channel IDです)の2個を最低限持たせる必要があるようです。あと任意でnonce
とかuser_id
を持たせられるようです。
post_form
RailsからHTTPリクエストを送るのにpost_form
ってやつが簡単そうだったので使ってみました。
Railsサーバー側で取得したユーザー情報をフロントで表示する。
fetch(request) .then(response => response.json()) .then(data => { console.log(data) iss_field.append(data.iss) sub_field.append(data.sub) aud_field.append(data.aud) exp_field.append(data.exp) iat_field.append(data.iat) authTime_field.append(data.auth_time) nonce_field.append(data.nonce) amr_field.append(data.amr) name_field.append(data.name) picture_field.append(data.picture) email_field.append(data.email) })
この辺でやってるやつです。Railsから渡したjsonの情報を表示してるだけです。
参考文献
RubyのHTTPリクエストをできるだけシンプルに実装する - Qiita library net/http (Ruby 3.0.0 リファレンスマニュアル) LINEログイン v2.1 APIリファレンス | LINE Developers 参考になりましたありがとうございました
最後に
解釈が間違っているところやここは違うやり方に変えた方がいいよなどありましたらお願いします。