fix api
This commit is contained in:
parent
01b8951dd5
commit
10ebc59ffb
17 changed files with 1087 additions and 238 deletions
|
@ -96,6 +96,28 @@ func GetUserIDFromContext(ctx context.Context) (string, error) {
|
|||
return userID, nil
|
||||
}
|
||||
|
||||
// ValidateToken validates a JWT token and returns the claims
|
||||
func ValidateToken(tokenString string, signingKey string) (*Claims, error) {
|
||||
claims := &Claims{}
|
||||
token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
|
||||
// Validate signing method
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
||||
}
|
||||
return []byte(signingKey), nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !token.Valid {
|
||||
return nil, fmt.Errorf("invalid token")
|
||||
}
|
||||
|
||||
return claims, nil
|
||||
}
|
||||
|
||||
// RequireAuth is a middleware that ensures a valid JWT token is present
|
||||
func RequireAuth(signingKey string, next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
73
auth/refresh.go
Normal file
73
auth/refresh.go
Normal file
|
@ -0,0 +1,73 @@
|
|||
package auth
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
)
|
||||
|
||||
// RefreshRequest represents the request body for token refresh
|
||||
type RefreshRequest struct {
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
}
|
||||
|
||||
// RefreshResponse represents the response body for token refresh
|
||||
type RefreshResponse struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
}
|
||||
|
||||
// HandleRefresh handles the token refresh request
|
||||
func HandleRefresh(w http.ResponseWriter, r *http.Request, signingKey string, accessExpiry, refreshExpiry time.Duration) {
|
||||
// Only accept POST requests
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
// Parse request body
|
||||
var req RefreshRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
http.Error(w, "Invalid request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Validate refresh token
|
||||
claims := &Claims{}
|
||||
token, err := jwt.ParseWithClaims(req.RefreshToken, claims, func(token *jwt.Token) (interface{}, error) {
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, jwt.ErrSignatureInvalid
|
||||
}
|
||||
return []byte(signingKey), nil
|
||||
})
|
||||
|
||||
if err != nil || !token.Valid {
|
||||
http.Error(w, "Invalid refresh token", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
// Generate new access token
|
||||
accessToken, err := GenerateToken(claims.UserID, signingKey, accessExpiry)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to generate access token", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Generate new refresh token
|
||||
refreshToken, err := GenerateToken(claims.UserID, signingKey, refreshExpiry)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to generate refresh token", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Return new tokens
|
||||
resp := RefreshResponse{
|
||||
AccessToken: accessToken,
|
||||
RefreshToken: refreshToken,
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(resp)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue