feat(auth): M2 conflict_ticket 令牌(编码已验证 openid+phone)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
guke
2026-07-14 17:21:52 +08:00
parent af615a9853
commit f8b5d31d2e
2 changed files with 75 additions and 0 deletions
+29
View File
@@ -47,3 +47,32 @@ def _occupy_via_conflict(client, monkeypatch, openid: str, phone: str, device_id
def test_phone_rebind_log_model_importable() -> None:
assert PhoneRebindLog.__tablename__ == "phone_rebind_log"
# ===== Task 2: conflict_ticket 令牌 =====
def test_conflict_ticket_roundtrip() -> None:
token = security.create_conflict_ticket(
openid="oid1", wechat_nickname="", wechat_avatar_url="http://a", phone="13900139000"
)
claims = security.decode_conflict_ticket(token)
assert claims["openid"] == "oid1"
assert claims["wnk"] == ""
assert claims["wav"] == "http://a"
assert claims["phone"] == "13900139000"
def test_conflict_ticket_wrong_type_rejected() -> None:
# bind_ticket 冒充 conflict_ticket → TokenError(typ 不匹配)
bind = security.create_bind_ticket(openid="oid", wechat_nickname=None, wechat_avatar_url=None)
with pytest.raises(security.TokenError):
security.decode_conflict_ticket(bind)
def test_conflict_ticket_expired_rejected(monkeypatch) -> None:
monkeypatch.setattr(security.settings, "WECHAT_BIND_TICKET_EXPIRE_MINUTES", -1)
token = security.create_conflict_ticket(
openid="oid", wechat_nickname=None, wechat_avatar_url=None, phone="13900139000"
)
with pytest.raises(security.TokenError):
security.decode_conflict_ticket(token)