http.frm.auth
认证三件套(P6-C;cookie 解析/签发 + HMAC 签名 会话令牌 + JWT HS256 + own 盒会话存储)
语义登记(v1 口径,偏离/志向逐条):
① Cookie 面:auth_cookie_get = Cookie 头 "a=b; c=d" 名精确匹配取值
(零解码 —— 值域即签发域 [A-Za-z0-9_-.],percent/plus 解码登记缺席,
从严;DQuote 包裹值(RFC 6265 §5.2 容许形)登记缺席)。auth_cookie_set
= Set-Cookie 行构造:属性序【恒】 Path=/; HttpOnly?; Max-Age=?;
SameSite=Lax(csrf.ct Task-3 对齐登记:Path 前置、SameSite=Lax 收尾,
会话版增 HttpOnly/Max-Age 居中 —— HttpOnly 先、Max-Age 后,序登记);
maxage < 0 = 会话 cookie(不发 Max-Age);maxage >= 0 恒发(Max-Age=0
= 即刻过期删除面,RFC 6265 §5.2.2)。构造期校验(注入面封口):name =
RFC 9110 tchar 域 1..64,value = cookie-octet 窄域(0x21..0x7E 去
DQUOTE/逗号/分号/反斜杠)0..4096 —— name/value 任一出域 → 返回 ""
(空行 = 构造拒;CR/LF/控制字节不可达 → 头走私面封口,csrf 同口径)。
② 签名会话令牌(无状态;own 盒存储之对偶):auth_tok_issue(key, uid, now, ttl) → tok = uid "." exp "." hex(HMAC-SHA256(key, uid "." exp)) (csrf 签名对同构,值携过期 —— exp = now+ttl unix_ms 十进制)。校验 auth_tok_verify(key, tok, now):形(恰两点、域、exp 数、sig 64 hex) → 签名重算恒时比较(csrf cr_ct_eq 算术平方累计同式,本模块私铸 —— 直引即同叶双径)→ 过期判(now >= exp 拒,RFC 7519 §4.1.4「须早于」 字面口径,jwt exp 同规)。uid 域 = [A-Za-z0-9_-]{1,64}(cookie 安全)。
③ JWT HS256(RFC 7515/7519):header 钉死 {"alg":"HS256","typ":"JWT"}
—— 校验面对收报首段(b64url)与钉形常量 auth_jwt_hdr_b64 【整串字节
等值】判,alg=none/RS256/缺 typ/任意增删字段一概异形即拒
(auth_err_alg=9;alg 混淆防护 = 钉形即防护,自定义 header(kid 等)列
志向;常量与字面 header 的编码等值有 inline 测试互钉)。签名段 =
base64url(HMAC-SHA256(key, header_b64 "." payload_b64))(无填充
RFC 7515;字母表 -_);b64url 自出 lane-b64(ws.ct 先例:std/enc
b64_decode 入 C8 printable 域且标准字母表,不取)。恒时比较在【编码域】
进行(重算期待 b64url 串 vs 收报 sig 段,解码不需要)。载荷 b64url 解码
= List[I32] 字节道(router.ct body 绑定字节道登记同向;Str 表格构建面
—— byte_slice 可印表 —— 载不下 123 '{' 字节,故 claims 扫描直接走
字节,任意字节载荷可解)。claims 扫描 = 平面字节扫 "name" : 后
整数 token(首现胜出/重复键登记;字符串值内引号假象登记 v1 限 —— 载荷
恒 composition 层经 std/json write 面产出)。exp/iat/nbf 判:
exp 缺省可过(RFC 7519 不强制;required 模式列志向)/ now >= exp 拒 /
nbf now < nbf 拒(§4.1.5「on or after」)/ iat 恒 iat <= now(零钟差
从严档,登记)。RS256 = 志向(纯层无 RSA;登记)。
④ own 盒会话存储(有状态对偶;外置 Redis 列 P8 注记):SessStore = 显式值状态(8 槽定容;组合层持有并以值重建下传 —— limit.ct LimBkt 先例;纯层无全局无可变量)。put = upsert(同 sid 原槽替换;新 sid 落 首空槽,次占过期槽 —— now >= e 判;满 → why 14 原样返回)。get = 1 命中有效(now < e)/ 0 miss / -1 过期(组合层决定删)。del/gc = 值重建。sid 熵源 = composition 层注入(uuid_v4/随机 —— csrf nonce 同 口径,纯层无熵);时钟恒注入参数 now(unix_ms)—— limit.ct 确定性 先例,真钟装配归组合层(std.time Clock 出面)。
注入面:Set-Cookie 值/name 恒经构造域校验(①);tok/jwt 值域 = 签发 域(token 字符);Retry 类无。请求侧取值面产出只进校验比较面。
use 面:std.crypto 单叶(hmac_sha256/bytes_to_hex —— csrf.ct 同款; 消费方若自用 std.crypto 再 use 本模块 = 同叶双径 E5020,禁)。常时 比较/字位面私铸不导(防菱形);【禁】use std.json(claims 平面字节扫, 见 ③)—— body.ct 另持 json 叶,两模块可在同一 fixture 并用而 json 单径不菱形。byte_at/byte_slice = 内建(零 use)。【utf8_enc 内建禁用】 P6-C 实证:解释臂恒产 U+FFFD 替换列(0xEF 0xBF 0xBD),emit 臂真编码 —— 双臂语义劈叉,单字节 Str 构建恒走 au_ch 表格面(csrf/ws 同式)。
pub struct
struct AuthTok
| Field | Type |
|---|---|
ok |
I64 |
why |
I64 |
tok |
Str |
struct TokVer
| Field | Type |
|---|---|
rc |
I64 |
why |
I64 |
uid |
Str |
struct AuthClaim
claims 平面扫描结果(k: 1 命中 / 0 缺 / -1 命中但值非整数形;首现胜出)
| Field | Type |
|---|---|
k |
I64 |
v |
I64 |
struct JwtVer
| Field | Type |
|---|---|
rc |
I64 |
why |
I64 |
struct SessStore
| Field | Type |
|---|---|
n |
I64 |
e0 |
I64 |
e1 |
I64 |
e2 |
I64 |
e3 |
I64 |
e4 |
I64 |
e5 |
I64 |
e6 |
I64 |
e7 |
I64 |
s0 |
Str |
s1 |
Str |
s2 |
Str |
s3 |
Str |
s4 |
Str |
s5 |
Str |
s6 |
Str |
s7 |
Str |
r0 |
Str |
r1 |
Str |
r2 |
Str |
r3 |
Str |
r4 |
Str |
r5 |
Str |
r6 |
Str |
r7 |
Str |
struct SessPut
| Field | Type |
|---|---|
ok |
I64 |
why |
I64 |
st |
SessStore |
struct SessGet
| Field | Type |
|---|---|
rc |
I64 |
user |
Str |
pub fn
| Signature | Returns | Description |
|---|---|---|
auth_err_ok() |
I64 |
— |
auth_err_empty() |
I64 |
— |
auth_err_shape() |
I64 |
— |
auth_err_uid() |
I64 |
— |
auth_err_expnum() |
I64 |
— |
auth_err_sigform() |
I64 |
— |
auth_err_sig() |
I64 |
— |
auth_err_expired() |
I64 |
— |
auth_err_b64() |
I64 |
— |
auth_err_alg() |
I64 |
— |
auth_err_nbf() |
I64 |
— |
auth_err_iat() |
I64 |
— |
auth_err_claim() |
I64 |
— |
auth_err_full() |
I64 |
— |
auth_cookie_get(cookie_hdr: Str, name: Str) |
Str |
Cookie 头值 "a=b; c=d" → 名精确匹配值(无 → "";首匹配胜出;零解码) |
auth_cookie_set(name: Str, value: Str, maxage: I64, httponly: I64) |
Str |
Set-Cookie 行(属性序登记见头注①;CRLF 自备)。构造期校验:任一出域 → ""(注入面封口:CR/LF/控制字节/裸逗号分号反斜杠 DQUOTE 不可达)。 maxage < 0 = 会话 cookie(无 Max-Age);>= 0 恒发(0 = 删除面)。 |
at_ok(t: AuthTok) |
I64 |
— |
at_why(t: AuthTok) |
I64 |
— |
at_tok(t: AuthTok) |
Str |
— |
auth_tok_issue(key: Str, uid: Str, now: I64, ttl: I64) |
AuthTok |
签发:tok = uid "." exp "." hex(HMAC-SHA256(key, uid "." exp)) |
tv_rc(v: TokVer) |
I64 |
— |
tv_why(v: TokVer) |
I64 |
— |
tv_uid(v: TokVer) |
Str |
— |
auth_tok_verify(key: Str, tok: Str, now: I64) |
TokVer |
校验:形 → 签名重算恒时比较 → 过期(now >= exp 拒,RFC 7519 §4.1.4 口径) |
auth_b64url_encode(src: Str) |
Str |
b64url 编码(入参任意字节面 —— byte_at 逐字节,出参恒 ASCII;无填充) |
auth_jwt_hdr() |
Str |
钉死 JWT header(alg 混淆防护 = 整串字节等值钉形判,头注③) |
ac_k(c: AuthClaim) |
I64 |
— |
ac_v(c: AuthClaim) |
I64 |
— |
auth_jwt_claim(payload: Str, name: Str) |
AuthClaim |
公开面(载荷 Str 域;composition 侧查询)—— 字节道同一扫描 |
auth_jwt_sign(key: Str, payload: Str) |
AuthTok |
JWT 签发(结果面 = AuthTok 复用,at_* getter):tok = b64u(hdr) "." b64u(payload) "." b64u(HMAC-SHA256(key, hdr_b64 "." pay_b64))(载荷逐字 签入,本模块不校验载荷 JSON —— composition 层经 std/json write 面产出, 登记头注③) |
auth_jwt_hdr_b64() |
Str |
钉死 header 的 b64url 形(常量;校验面以收报首段整串等值钉形判 —— alg 混淆防护:alg=none/HS512/RS256/字段增删一概异形即拒) |
jwt_rc(v: JwtVer) |
I64 |
— |
jwt_why(v: JwtVer) |
I64 |
— |
auth_jwt_verify(key: Str, tok: Str, now: I64) |
JwtVer |
校验序(登记):空/形 → b64url 三段形 → header 钉形(整串等值,alg 混淆 拒)→ 签名重算恒时比较(编码域)→ 载荷解码(字节道)→ exp → nbf → iat。claims 皆缺省可过(RFC 7519 不强制;required 模式列志向)。 |
auth_sess_cap() |
I64 |
— |
auth_sess_new() |
SessStore |
— |
sp_ok(p: SessPut) |
I64 |
— |
sp_why(p: SessPut) |
I64 |
— |
sp_st(p: SessPut) |
SessStore |
— |
auth_sess_put(t: SessStore, sid: Str, user: Str, now: I64, ttl: I64) |
SessPut |
upsert:同 sid 原槽替换;新 sid 落首空槽,次占首个过期槽(now >= e); 满 → ok=0/why=14 原样返回(逐出策略归组合层) |
sg_rc(g: SessGet) |
I64 |
— |
sg_user(g: SessGet) |
Str |
— |
auth_sess_get(t: SessStore, sid: Str, now: I64) |
SessGet |
取:1 命中有效(now < e)/ 0 miss / -1 过期(删否归组合层) |
auth_sess_del(t: SessStore, sid: Str) |
SessStore |
删(不存在原样返回) |
auth_sess_gc(t: SessStore, now: I64) |
SessStore |
清扫过期(now >= e 全删;组合层周期驱动的便捷面) |
auth_sess_len(t: SessStore) |
I64 |
活跃会话数 |