😇

Shopify MultipassでSSOしたら、都道府県とログアウトでハマった思い出話

に公開

Shopify Plus限定の「Multipass Login」でSSOを実装してみたら、実装そのものは拍子抜けするほど簡単でした。
しかし、細かいところで地味に時間を吸われる仕様がありました。

特にハマったのがこの2点です。

  • 都道府県が正しく連携されない
  • ログアウトができない

Multipass自体の情報は多いですが、この2点に触れている記事はほとんどなかったので、備忘録としてまとめておきます。


Multipass Loginとは

Shopify Plusで使えるSSO機能で、外部サイトのユーザーをShopifyストアにログインさせる仕組みです。

仕組みはシンプルで、JWTトークンを暗号化してHMAC署名し、Shopifyに渡すだけです。
ドキュメント通りにやれば数分で動きます。

const payload = {
  email: "user@example.com",
  first_name: "竜也",
  last_name: "兵藤",
  return_to: "https://your-store.myshopify.com/account",
};

このpayloadを暗号化 → HMAC署名 →
https://your-store.myshopify.com/account/login/multipass/{token} にリダイレクトすればログインできます。

ここまでは問題なし。
本当の戦いは「住所を渡した時」から始まります。


都道府県が連携されない問題

最初はこんな感じで住所情報を渡していました。

address1: "六本木1-2-3",
city: "港区",
province: "東京都",
province_code: "13",
country: "Japan",
country_code: "JP"

結果、Shopifyストアのマイページには都道府県が空欄
市区町村までは入っているのに、都道府県だけスルーされます。

試しに "Tokyo""TOKYO" にしてもダメ。
ISOコード形式にしても反映されない。
いろいろ試してやっと分かりました。

正解はこれです。

'country' => 'Japan',
'country_code' => 'JP',
'province' => 'Tōkyō',
'Province code' => '13',

はい、「Tōkyō」です。
謎のローマ字表記で、長音符つき。
しかも「Province code」だけなぜかスネークケースではない。

ほんと最低な仕様。

Shopifyの公式ドキュメントにはこの仕様が一切書かれていません。
唯一このQ&Aで上記情報を見つけられました。ありがとう、ありがとう・・!

「Japanを指定したら都道府県ぐらい自動で判定してくれるだろう」と思ったら全くしてくれません。
ローマ字の表記をミスると無言で無視されます。

英語表記一覧を置いておきます。

    'prefecture_en_list' => [
        1 => 'Hokkaidō',
        2 => 'Aomori',
        3 => 'Iwate',
        4 => 'Miyagi',
        5 => 'Akita',
        6 => 'Yamagata',
        7 => 'Fukushima',
        8 => 'Ibaraki',
        9 => 'Tochigi',
        10 => 'Gunma',
        11 => 'Saitama',
        12 => 'Chiba',
        13 => 'Tōkyō',
        14 => 'Kanagawa',
        15 => 'Niigata',
        16 => 'Toyama',
        17 => 'Ishikawa',
        18 => 'Fukui',
        19 => 'Yamanashi',
        20 => 'Nagano',
        21 => 'Gifu',
        22 => 'Shizuoka',
        23 => 'Aichi',
        24 => 'Mie',
        25 => 'Shiga',
        26 => 'Kyōto',
        27 => 'Ōsaka',
        28 => 'Hyōgo',
        29 => 'Nara',
        30 => 'Wakayama',
        31 => 'Tottori',
        32 => 'Shimane',
        33 => 'Okayama',
        34 => 'Hiroshima',
        35 => 'Yamaguchi',
        36 => 'Tokushima',
        37 => 'Kagawa',
        38 => 'Ehime',
        39 => 'Kōchi',
        40 => 'Fukuoka',
        41 => 'Saga',
        42 => 'Nagasaki',
        43 => 'Kumamoto',
        44 => 'Ōita',
        45 => 'Miyazaki',
        46 => 'Kagoshima',
        47 => 'Okinawa',
    ]

ログアウトできない問題

もう一つハマったのがログアウト。

Multipassは「ログイン専用」の仕組みで、ログアウトは提供されていません。

外部サイトでセッションを切っても、Shopify側のログインは生きたまま。
結果、再ログインしても同じユーザーが勝手に復活します。

「logout API があるはず」と思って探してもありません。
「Shopify Admin APIでセッションを無効化できるのでは?」と思ってもできません。

結論として、Shopifyの/account/logoutにリダイレクトするという力技で解決できるようでした。

app.get("/logout", (req, res) => {
  req.session.destroy();
  res.redirect("https://your-store.myshopify.com/account/logout");
});

外部システムとShopifyの両方のセッションをここで削除します。
共通のログアウトページを用意して、両方の処理をまとめるのが一番シンプルです。


まとめ

Multipassは動くには動く。
ただし、気持ちよくは動かない。

  • 都道府県は「Tōkyō」とかいう謎の表記を要求される
  • 「Province code」だけキャメルケースという不思議仕様
  • ログアウトは自前で処理しないと残る

実装自体は簡単でも、細部でつまずく。
これからMultipassを使う人は、英語表記の沼とログアウト問題に気をつけてください。

oneframe

Discussion