feat(07.4-02): add _compute_fgp helper + extend create_access_token with fgp claim
- Add _compute_fgp(user_agent, accept_lang) helper returning 16-char hex HMAC-SHA256 fingerprint (D-04); uses existing hmac + hashlib imports - Extend create_access_token signature with user_agent/accept_lang params (empty-string defaults for backward compatibility, D-05) - Embed fgp claim in every issued access token payload
This commit is contained in:
@@ -84,10 +84,25 @@ def validate_password_strength(password: str) -> None:
|
|||||||
|
|
||||||
# ── JWT helpers ─────────────────────────────────────────────────────────────────
|
# ── JWT helpers ─────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
def create_access_token(user_id: str, role: str) -> str:
|
def _compute_fgp(user_agent: str, accept_lang: str) -> str:
|
||||||
|
"""Return 16-char hex fingerprint binding a token to its client context (D-04)."""
|
||||||
|
return hmac.new(
|
||||||
|
settings.secret_key.encode(),
|
||||||
|
(user_agent + accept_lang).encode(),
|
||||||
|
hashlib.sha256,
|
||||||
|
).hexdigest()[:16]
|
||||||
|
|
||||||
|
|
||||||
|
def create_access_token(
|
||||||
|
user_id: str,
|
||||||
|
role: str,
|
||||||
|
user_agent: str = "",
|
||||||
|
accept_lang: str = "",
|
||||||
|
) -> str:
|
||||||
"""Return a signed JWT access token.
|
"""Return a signed JWT access token.
|
||||||
|
|
||||||
Claims: sub=user_id, role=role, typ='access', exp=now+access_token_expire_minutes.
|
Claims: sub=user_id, role=role, typ='access', exp=now+access_token_expire_minutes,
|
||||||
|
fgp=fingerprint computed from client User-Agent + Accept-Language headers (D-05).
|
||||||
"""
|
"""
|
||||||
now = datetime.now(timezone.utc)
|
now = datetime.now(timezone.utc)
|
||||||
payload = {
|
payload = {
|
||||||
@@ -97,6 +112,7 @@ def create_access_token(user_id: str, role: str) -> str:
|
|||||||
"iat": now,
|
"iat": now,
|
||||||
"exp": now + timedelta(minutes=settings.access_token_expire_minutes),
|
"exp": now + timedelta(minutes=settings.access_token_expire_minutes),
|
||||||
"jti": str(uuid.uuid4()),
|
"jti": str(uuid.uuid4()),
|
||||||
|
"fgp": _compute_fgp(user_agent, accept_lang),
|
||||||
}
|
}
|
||||||
private_pem = base64.b64decode(settings.jwt_private_key).decode()
|
private_pem = base64.b64decode(settings.jwt_private_key).decode()
|
||||||
return jwt.encode(payload, private_pem, algorithm="ES256")
|
return jwt.encode(payload, private_pem, algorithm="ES256")
|
||||||
|
|||||||
Reference in New Issue
Block a user