POST /users/login_once.json

快速結論

  • 狀態:已補 legacy parity guard / fallback 與 PHPUnit;已做 staging happy / consumed / DB side effect 實測,完整 staging full diff 待補。
  • 正式機 access log 統計見 API 路由與遷移/API Migration/pro360_api_82/api_migration/users.mdPOST /users/login_once.json 63663 筆 200OPTIONS 37191 筆。
  • 這支用 security_hashes 建立一次性 session;會寫 api_sessionssecurity_hash_use_logsuser_logins
  • 2026-06-29 已補 active user guard、hash consumed guard、nested User.device_id fallback;只改 Users::login_once(),未改 shared SecurityHash model。

Legacy 對照

檔案行號行為
/Users/mattsu/Documents/Site/get-lancer-php56/app/Controller/UsersController.php2417-2435先找 SecurityHash.model = Session,找不到再找 User;找不到回 error=2
同上2438-2445users.id = user_id AND is_active = 1,不符合回 error=2
同上2446-2464Session hash 14 天前或已 fulfilled 視為 consumed;已 fulfilled 的 ibonHyperlinkLogin / OrderLoginUrl 也 consumed
同上2466-2468device id 優先 User.device_id,再 fallback flat device_id,最後 my-device-id
同上2470-2495建 session、fulfill Session 或 count User click、寫 use log、寫 channel 2 user login

New 對照

檔案行號行為
Endpoint/V1/Users.php478-529Users::login_once() 主流程
Endpoint/V1/Users.php492-499active user guard 與 hash consumed guard
Endpoint/V1/Users.php501-524建 session、fulfill / count click、寫 use log、寫 channel 2 user login
Endpoint/V1/Users.php531-567login_once 專用 legacy helper:active user、consumed hash、device id fallback

2026-06-29 差異清單

項目LegacyNew 目前判斷
active user guardusers.id = user_id AND is_active = 1,不符合回 invalid hash已補已對齊
Session hash 14 天 / fulfilled guardSession created <= 14 days ago 或 fulfilled 回 consumed已補已對齊
fulfilled ibon / order scenefulfilled 且 scene 是 ibonHyperlinkLogin / OrderLoginUrl 回 consumed已補已對齊
device id fallbackUser.device_id -> flat device_id -> my-device-id已補已對齊

測試結果

docker exec -w /project-data cd63f9147e8d php -l Endpoint/V1/Users.php
docker exec -w /project-data cd63f9147e8d php -l tests/UsersLoginOnceTest.php
docker exec -w /project-data cd63f9147e8d vendor/bin/phpunit tests/UsersLoginOnceTest.php
OK (5 tests, 50 assertions)
docker exec -w /project-data cd63f9147e8d vendor/bin/phpunit tests/UsersForgotPasswordTest.php
OK (3 tests, 39 assertions)
docker exec -w /project-data cd63f9147e8d vendor/bin/phpunit tests/UsersSignUpTest.php
OK (11 tests, 129 assertions)

Staging 實測

2026-06-29 staging 已用 hash = 4f48b7e16e1e8c1420e93be77ffc3babuser_id = 15801 驗證:

  • 第一次呼叫回 {"error":0,"session_id":"6h9rmece3ac0pgemn5h4r53sgm"}
  • 第二次同 hash 回 {"error":1,"message":"hash was consumed"}
  • DB 確認 security_hashes.is_fulfilled = 1api_sessions 建立、security_hash_use_logs 寫入、user_logins.channel = 2

UsersLoginOnceTest.php 覆蓋:

  • 成功建立 session,consume Session hash,寫 security_hash_use_logs / user_logins,並使用 nested User.device_id
  • inactive user 回 invalid hash 且不建立 session。
  • expired Session hash 回 consumed 且不建立 session。
  • fulfilled regular Session hash 回 consumed 且不建立 session。
  • fulfilled ibonHyperlinkLogin / OrderLoginUrl 回 consumed 且不建立 session。

待確認

  • 尚未做完整 staging full diff;目前只驗證 happy path、二次 consumed 與主要 DB side effect。
  • SecurityHash::getByHash('User') 的時間條件 new 是 created > threshold,legacy 是 created >= threshold;14 天邊界差異極小,暫未改動。