v1.1.1 — Session-Token statt JWT für Account-Calls
Wire-Konvention für authenticated Account-Endpoints (changeEmail, changePassword, deleteAccount) geklärt. Server-seitig wurde in mana-auth Better Auths bearer-Plugin aktiviert (requireSignature: false), das Session-Tokens zu Session-Cookies konvertiert. Native- Apps senden daher jetzt den Session-Token (refreshToken-Feldwert) statt des JWT als Authorization: Bearer für diese drei Endpoints. Der JWT bleibt für app-eigene Backends (memoro-api, cardecky-api, manaspur-api) der richtige Authorization-Header — die Trennung ist nur für mana-auth interne Endpoints. currentSessionToken() als public Helper hinzu (symmetrisch zu currentAccessToken). 38/38 Tests grün. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
716509e10e
commit
3459c78731
4 changed files with 68 additions and 16 deletions
|
|
@ -17,16 +17,19 @@ import Foundation
|
|||
/// - `POST /change-password` — Passwort ändern (current + new)
|
||||
/// - `DELETE /account` — Account löschen (App-Store-Pflicht 5.1.1(v))
|
||||
///
|
||||
/// **Server-Limitation (Stand 2026-05-13):** `change-email`,
|
||||
/// `change-password` und `DELETE /account` forwarden Original-Request-
|
||||
/// Headers an Better Auth. Better Auth liest Session-Cookies. Der
|
||||
/// `bearer`-Plugin von Better Auth ist NICHT installiert, daher
|
||||
/// scheitern diese Endpoints heute mit reinem `Authorization: Bearer`.
|
||||
/// → Server-Fix in Phase 3 nötig (entweder `bearerPlugin()` in
|
||||
/// `better-auth.config.ts` aktivieren oder Custom-Bearer-Resolver in
|
||||
/// `mana-auth/src/routes/auth.ts` ergänzen). ManaCore sendet Bearer
|
||||
/// bereits korrekt — sobald der Server das akzeptiert, funktionieren
|
||||
/// die Methoden ohne Swift-Änderung.
|
||||
/// **Wire-Konvention für authenticated Account-Calls:**
|
||||
/// `change-email`, `change-password` und `DELETE /account` forwarden
|
||||
/// die Original-Request-Headers an Better Auth (`auth.api.changeEmail`
|
||||
/// etc.). Better Auth's `bearer`-Plugin (seit 2026-05-13 in mana-auth
|
||||
/// aktiv) konvertiert `Authorization: Bearer <session-token>` in
|
||||
/// einen synthetischen Session-Cookie. **Native-Apps senden hier den
|
||||
/// Session-Token (`refreshToken`-Feldwert aus /login bzw. /refresh),
|
||||
/// NICHT den JWT.** Der JWT bleibt für app-eigene Backends
|
||||
/// (memoro-api, cardecky-api etc.) der richtige Header.
|
||||
///
|
||||
/// Trade-Off: Session-Token wird häufiger versendet als der reine
|
||||
/// Refresh-Pfad. Bei TLS-only-Baseline akzeptabel; Compromise-Surface
|
||||
/// nicht relevant größer als JWT-Leak.
|
||||
public extension AuthClient {
|
||||
// MARK: - Registrierung
|
||||
|
||||
|
|
@ -296,7 +299,9 @@ public extension AuthClient {
|
|||
|
||||
extension AuthClient {
|
||||
/// Generischer JSON-POST/DELETE-Helper. Wenn `authenticated == true`,
|
||||
/// wird der aktuelle Bearer-Token mitgeschickt.
|
||||
/// wird der Session-Token (`refreshToken`-Feldwert, von Better Auth
|
||||
/// als Session-ID interpretierbar via `bearer`-Plugin) als Bearer-
|
||||
/// Header mitgeschickt — NICHT der JWT. Siehe Doc-Header dieser Datei.
|
||||
fileprivate func postJSON<Body: Encodable>(
|
||||
path: String,
|
||||
method: String = "POST",
|
||||
|
|
@ -308,7 +313,7 @@ extension AuthClient {
|
|||
request.httpMethod = method
|
||||
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||
if authenticated {
|
||||
let token = try currentAccessToken()
|
||||
let token = try currentSessionToken()
|
||||
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
|
||||
}
|
||||
do {
|
||||
|
|
|
|||
|
|
@ -133,6 +133,19 @@ public final class AuthClient {
|
|||
return token
|
||||
}
|
||||
|
||||
/// Liefert den Session-Token (das wire-protocol `refreshToken`-Feld).
|
||||
/// Wird von Better-Auth-`auth.api.*`-Endpoints akzeptiert wenn der
|
||||
/// `bearer`-Plugin server-seitig aktiv ist — z.B. für `changeEmail`,
|
||||
/// `changePassword`, `deleteAccount`. Der App-eigene JWT (aus
|
||||
/// `currentAccessToken`) gilt für app-spezifische Backends, der
|
||||
/// Session-Token nur für mana-auths Account-Aktionen.
|
||||
public func currentSessionToken() throws -> String {
|
||||
guard let token = keychain.getString(for: .refreshToken) else {
|
||||
throw AuthError.notSignedIn
|
||||
}
|
||||
return token
|
||||
}
|
||||
|
||||
/// Liefert einen Access-Token, der nicht innerhalb der nächsten
|
||||
/// `refreshLeeway` Sekunden abläuft. Refreshed proaktiv, wenn nötig.
|
||||
public func freshAccessToken(refreshLeeway: TimeInterval = 300) async throws -> String {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue