feat(api): REST на chi + huma с auth-ручками и OpenAPI 3.1
- переход на chi + huma (решение D-006): huma отдаёт типизированные ручки и генерирует документ, auth-ручки живут на chi (cookie и заголовки напрямую) - единый формат ошибок: код (auth.invalid_credentials, auth.2fa_required, perm.denied и т.д.) + человекочитаемое сообщение (AGENT.md 8.5) - cookie сессии __Host-session: HttpOnly, SameSite=Lax, Secure при TLS; альтернатива — Bearer-токен для desktop/CLI (AGENT.md 8.1) - ручки: register, login, logout, logout-all, sessions, step-up, 2fa/setup, 2fa/enable, users/@me; IP и User-Agent прокидываются из запроса в контекст - /api/v1/openapi.json: объединённый документ (схемы huma + контракт auth) - тесты: регистрация через API с cookie, ошибки входа, обязательная сессия, валидация, наличие всех путей в OpenAPI
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
package httpx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func newRequestID() string {
|
||||
@@ -12,3 +14,32 @@ func newRequestID() string {
|
||||
}
|
||||
return hex.EncodeToString(buf[:])
|
||||
}
|
||||
|
||||
type requestInfoKey struct{}
|
||||
|
||||
// RequestInfo — данные исходного запроса, нужные сервисам (IP, User-Agent).
|
||||
type RequestInfo struct {
|
||||
IP string
|
||||
UserAgent string
|
||||
}
|
||||
|
||||
// WithRequestInfo кладёт данные запроса в контекст (используется HTTP-слоем).
|
||||
func WithRequestInfo(ctx context.Context, r *http.Request) context.Context {
|
||||
return context.WithValue(ctx, requestInfoKey{}, RequestInfo{
|
||||
IP: ClientIP(r, nil),
|
||||
UserAgent: r.Header.Get("User-Agent"),
|
||||
})
|
||||
}
|
||||
|
||||
func requestInfo(ctx context.Context) RequestInfo {
|
||||
if info, ok := ctx.Value(requestInfoKey{}).(RequestInfo); ok {
|
||||
return info
|
||||
}
|
||||
return RequestInfo{}
|
||||
}
|
||||
|
||||
// ClientIPFromContext возвращает IP клиента для контекста huma.
|
||||
func ClientIPFromContext(ctx context.Context) string { return requestInfo(ctx).IP }
|
||||
|
||||
// UserAgentFromContext возвращает User-Agent для контекста huma.
|
||||
func UserAgentFromContext(ctx context.Context) string { return requestInfo(ctx).UserAgent }
|
||||
|
||||
Reference in New Issue
Block a user