-
Notifications
You must be signed in to change notification settings - Fork 0
Move Firebase auth into OpenAPI validator #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2,60 +2,145 @@ package middleware | |||||||||||
|
|
||||||||||||
| import ( | ||||||||||||
| "context" | ||||||||||||
| "errors" | ||||||||||||
| "net/http" | ||||||||||||
| "strings" | ||||||||||||
|
|
||||||||||||
| "firebase.google.com/go/v4/auth" | ||||||||||||
| "github.com/getkin/kin-openapi/openapi3filter" | ||||||||||||
| "github.com/gin-gonic/gin" | ||||||||||||
| ginmiddleware "github.com/oapi-codegen/gin-middleware" | ||||||||||||
| ) | ||||||||||||
|
|
||||||||||||
| type firebaseTokenKey struct{} | ||||||||||||
| type authErrorStatusKey struct{} | ||||||||||||
| type authErrorMessageKey struct{} | ||||||||||||
|
|
||||||||||||
| // FirebaseTokenContextKey は Gin の context および context.Context に | ||||||||||||
| // Firebase ID トークンの検証結果を格納するキーです。 | ||||||||||||
| var FirebaseTokenContextKey = firebaseTokenKey{} | ||||||||||||
|
|
||||||||||||
| var ( | ||||||||||||
| authenticationErrorStatusKey = authErrorStatusKey{} | ||||||||||||
| authenticationErrorMessageKey = authErrorMessageKey{} | ||||||||||||
| ) | ||||||||||||
|
|
||||||||||||
| type AuthenticationError struct { | ||||||||||||
| StatusCode int | ||||||||||||
| Message string | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| func (e *AuthenticationError) Error() string { | ||||||||||||
| return e.Message | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| // FirebaseAuthenticationFunc は OpenAPI validator 向けの AuthenticationFunc を返します。 | ||||||||||||
| // 認証に成功した場合は検証済みトークンを Gin / request context に格納します。 | ||||||||||||
| func FirebaseAuthenticationFunc(authClient *auth.Client) openapi3filter.AuthenticationFunc { | ||||||||||||
| return func(ctx context.Context, _ *openapi3filter.AuthenticationInput) error { | ||||||||||||
| ginCtx := ginmiddleware.GetGinContext(ctx) | ||||||||||||
| if ginCtx == nil { | ||||||||||||
| return &AuthenticationError{ | ||||||||||||
| StatusCode: http.StatusUnauthorized, | ||||||||||||
| Message: "Authentication context is unavailable", | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| token, err := verifyFirebaseToken(ginCtx.GetHeader("Authorization"), ginCtx.Request.Context(), authClient) | ||||||||||||
| if err != nil { | ||||||||||||
| var authErr *AuthenticationError | ||||||||||||
| if errors.As(err, &authErr) { | ||||||||||||
| ginCtx.Set(authenticationErrorStatusKey, authErr.StatusCode) | ||||||||||||
| ginCtx.Set(authenticationErrorMessageKey, authErr.Message) | ||||||||||||
| } | ||||||||||||
| return err | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| setFirebaseToken(ginCtx, token) | ||||||||||||
| return nil | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| // FirebaseAuth は Authorization: Bearer <Firebase ID Token> を検証する Gin ミドルウェアです。 | ||||||||||||
| // 検証に成功すると、デコードされたトークン(*auth.Token)を context に格納して次のハンドラに渡します。 | ||||||||||||
|
||||||||||||
| // 検証に成功すると、デコードされたトークン(*auth.Token)を context に格納して次のハンドラに渡します。 | |
| // 検証に成功すると、デコードされたトークン(*auth.Token)を context に格納して次のハンドラに渡します。 | |
| // Deprecated: このミドルウェアは現在サーバでは使用されていません。認証は OpenAPI validator を通じて | |
| // FirebaseAuthenticationFunc を用いて行われます。新しいコードでは FirebaseAuth ではなく | |
| // FirebaseAuthenticationFunc を利用してください。 |
Copilot
AI
Mar 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fallback branch that returns a generic 401 ("Authentication failed") is effectively unreachable right now because verifyFirebaseToken always returns an *AuthenticationError on failure. Consider removing the dead branch, or change verifyFirebaseToken to return non-auth errors distinctly (e.g., wrap unexpected errors as 500) so this branch can be meaningful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When
GetGinContext(ctx)returns nil, this indicates a server/middleware wiring issue rather than an authentication failure. Returning 401 here can mislead clients and hide operational problems; consider treating this as an internal error (e.g., 500) and/or ensuring the error handler does not expose this internal message to clients.