12. Stripe PHP vs Laravel Cashier認証Gemどうするの問題(課題1)
Q. SorceryやDeviseなしでも認証周り楽にする方法ないの?(課題1)
A. 「Knock」が使えました😆
13. Stripe PHP vs Laravel CashierAPIモードの認証ならKnock
APIモードのRailsアプリで、JWT認証が手軽にできるやつ
class Api::V1::HogePiyoController < ApplicationController
before_action :authenticate_user
def show
p current_user.id
end
14. Stripe PHP vs Laravel CashierRuby用のAdmin SDKない問題(課題2)
Q. Ruby用のFirebase Admin SDKがないみたいだけど、JWTの検証どうす
るの?(課題2)
A. 検証ぐらい自前でいったれ💪
(対応言語で実装してごにゃごにゃ連携するのもあり?)
15. Stripe PHP vs Laravel CashierKnockのちからを借りつつJWT検証
ApplicationController
# Knockの認証メソッドをオーバーライド
module Knock::Authenticable
def define_current_entity_getter(entity_class, getter_name)
# 中略
response = client.get("https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com")
jwks_raw = response.body
JSON.parse(jwks_raw).each do |_key, key_string|
jwks_string = key_string.gsub("-----BEGIN CERTIFICATE-----", "").gsub("-----END CERTIFICATE-----", "").delete("n")
Knock.token_signature_algorithm = "RS256"
Knock.token_public_key = OpenSSL::X509::Certificate.new(Base64.decode64(jwks_string)).public_key
begin
@payload = Knock::AuthToken.new(token: token).entity_for(entity_class)
break if @payload.present?
rescue
next
end
KnockにはJWTを公開鍵で検証する仕組みが備わっていますが、 公開鍵が固定になる
一方Firebaseの公開鍵は定期的に変更されるので、 動的に取得する必要がある
(遅くなるので鍵はキャッシュしておくと良い!)
16. Stripe PHP vs Laravel Cashierログイン&新規登録
User.rb
def self.from_token_payload(payload)
// Userが入れば取得
user = find_by(sub: payload["sub"])
// いなければ新規作成
user || create!(sub: payload["sub"],
user_name: payload["name"][0..29],
remote_image_url: payload["picture"].sub(/_normal./, "_bigger."))
end