fix(auth): enable RefreshToken endpoint for token renewal

Two critical authentication fixes:

1. **MetadataInterceptor**: Forward Cookie header to gRPC metadata
   - RefreshToken extracts refresh token from cookie via metadata
   - Previously only User-Agent, X-Forwarded-For, X-Real-Ip were forwarded
   - Added cookie forwarding to enable token refresh flow

2. **ACL Configuration**: Add RefreshToken to PublicMethods
   - RefreshToken must be accessible when access token has expired
   - Without this, clients cannot refresh expired access tokens
   - Now properly listed as public endpoint alongside CreateSession

These fixes enable the token refresh flow where clients can obtain
new access tokens using their refresh token cookie without re-authenticating.

Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Johnny 2025-12-18 15:33:56 +08:00
parent 0861258ded
commit 515cf93fc4
2 changed files with 5 additions and 0 deletions

View file

@ -12,6 +12,7 @@ var PublicMethods = map[string]struct{}{
// Auth Service - login flow must be accessible without auth
"/memos.api.v1.AuthService/CreateSession": {},
"/memos.api.v1.AuthService/GetCurrentSession": {},
"/memos.api.v1.AuthService/RefreshToken": {}, // Token refresh must be accessible when access token expired
// Instance Service - needed before login to show instance info
"/memos.api.v1.InstanceService/GetInstanceProfile": {},

View file

@ -43,6 +43,10 @@ func (*MetadataInterceptor) WrapUnary(next connect.UnaryFunc) connect.UnaryFunc
if xri := header.Get("X-Real-Ip"); xri != "" {
md.Set("x-real-ip", xri)
}
// Forward Cookie header for authentication methods that need it (e.g., RefreshToken)
if cookie := header.Get("Cookie"); cookie != "" {
md.Set("cookie", cookie)
}
// Set metadata in context so services can use metadata.FromIncomingContext()
ctx = metadata.NewIncomingContext(ctx, md)