三種憑據擇一:登入的會員、這個 session 剛下的單、信裡的簽章連結。


台灣的電商,訪客結帳佔比很高。客戶不想註冊,填完資料就付款走人。

問題來了:他要怎麼回來看訂單?

他沒有帳號可以登入,所以你不能用 user_id 比對。但訂單頁又不能隨便給人看——那裡面有姓名、電話、地址、買了什麼。

我看過最糟的做法,是網址帶 email:/orders/[email protected]。等於把客戶的個資放在網址上,而且還是可以被枚舉的。

我的三道放行

private function canView(Request $request, Order $order): bool
{
    // 一、這個瀏覽器剛下的單
    if (PlacedOrders::contains($order)) {
        return true;
    }

    // 二、訂單通知信裡的簽章連結
    if ($request->hasValidSignature()) {
        PlacedOrders::remember($order);   // 記進 session,之後瀏覽不必每次帶簽章

        return true;
    }

    if ($order->status === Order::STATUS_DRAFT) {
        return false;
    }

    // 三、會員看自己的訂單
    $user = $request->user();

    return $user !== null && $order->user_id === $user->id;
}

三條路,任一條成立就放行。

第一道:session 記住剛下的單

下單成功的當下,把訂單 id 記進 session:

PlacedOrders::remember($order);

所以客戶付完款跳回來、或是在站內來回點,都看得到。這涵蓋了「剛結帳完那段時間」,也是訪客最常需要看訂單的時候。

第二道:通知信裡的簽章連結

過幾天他想回來查,session 早就過期了。這時憑據是訂單通知信:

URL::signedRoute('account.orders.show', ['order' => $order->public_id]);

簽章連結被改一個字元就失效,所以他沒辦法改成別人的訂單。

我刻意沒有給這個連結到期時間。 因為客戶可能兩週後才想起來要查物流。到期的話,他只會收到一個「連結已失效」然後打電話給客服——那比讓連結長期有效的風險更實際。

注意驗證通過之後那行 PlacedOrders::remember($order):進來一次就記進 session,之後他在站內點來點去都不必再帶簽章。這是很小的一步,但體驗差很多。

設計原則

訪客的「身分」不存在,所以要改成驗證「憑據」。

憑據可以是:你剛剛做過這件事(session)、你收得到那封信(簽章連結)、你有帳號(登入)。

不要用「你知道這個 ID」當憑據,那不是憑據,那只是還沒被猜到而已。


⭐️ Shopify 網站開發服務(給品牌)
https://job.turn.tw/shopify-services

⭐️ 川川電商事務所(全客製電商開發服務)
https://chuanchuan.tw

⭐️ 台灣 Shopify 商家交流 LINE 群(非官方)
https://line.me/ti/g2/PZ_1LILWVWWuzZQ50HNpYA-A3k6QXWF6znqoBQ

⭐️ 台灣 Shopify 開發者 LINE 群(非官方)
https://line.me/ti/g2/YUasX5K3CJ4QdIx76zppjHlh3-q8w-xkSyK1LA

共有 0 則留言


⭐️ Shopify 網站開發服務(給品牌)
https://job.turn.tw/shopify-services

⭐️ 川川電商事務所(全客製電商開發服務)
https://chuanchuan.tw

⭐️ 台灣 Shopify 商家交流 LINE 群(非官方)
https://line.me/ti/g2/PZ_1LILWVWWuzZQ50HNpYA-A3k6QXWF6znqoBQ

⭐️ 台灣 Shopify 開發者 LINE 群(非官方)
https://line.me/ti/g2/YUasX5K3CJ4QdIx76zppjHlh3-q8w-xkSyK1LA
🏆 本月排行榜
🥇
站長阿川
📝45   💬1  
643
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次