refactor(auth): move authentication params to headers and simplify validation

- Move token and timestamp validation to HTTP headers
- Simplify ValidateTimeStamp to return boolean
- Update AddUser to use default "visitor" type
- Remove redundant timestamp and token fields from request structs
- Update API documentation to reflect header-based authentication
This commit is contained in:
2026-02-28 15:32:32 +08:00
parent 1f426f98e5
commit ff62e3e755
6 changed files with 113 additions and 134 deletions
+23 -62
View File
@@ -11,16 +11,13 @@ import (
)
type RegisterRequest struct {
Username string `json:"username"`
Passwd string `json:"passwd"`
TimeStamp int64 `json:"timeStamp"`
Type string `json:"type"`
Username string `json:"username"`
Passwd string `json:"passwd"`
}
type LoginRequest struct {
Username string `json:"username"`
Passwd string `json:"passwd"`
TimeStamp int64 `json:"timeStamp"`
Username string `json:"username"`
Passwd string `json:"passwd"`
}
type Response struct {
@@ -36,6 +33,11 @@ func RegisterHandler(w http.ResponseWriter, r *http.Request) {
return
}
if !ValidateTimeStamp(r.Header) {
SendErrorResponse(w, http.StatusBadRequest, "Invalid or missing X-Timestamp in header")
return
}
body, err := io.ReadAll(r.Body)
if err != nil {
SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
@@ -57,11 +59,6 @@ func RegisterHandler(w http.ResponseWriter, r *http.Request) {
return
}
if err := ValidateTimeStamp(req.TimeStamp); err != nil {
SendErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
if !isValidInput(req.Username) || !isValidInput(req.Passwd) {
SendErrorResponse(w, http.StatusBadRequest, "Invalid input: contains illegal characters")
postLog.Debug(fmt.Sprintf("[RegisterHandler] New user registration failed: username or password contains illegal characters \"%s\":\"%s\"", req.Username, req.Passwd))
@@ -74,23 +71,7 @@ func RegisterHandler(w http.ResponseWriter, r *http.Request) {
return
}
userType := req.Type
if userType == "" {
userType = "visitor"
}
validTypes := map[string]bool{
"superuser": true,
"admin": true,
"visitor": true,
}
if !validTypes[userType] {
SendErrorResponse(w, http.StatusBadRequest, "Invalid user type")
postLog.Warning(fmt.Sprintf("[RegisterHandler] New user registration failed: invalid user type \"%s\"", userType))
return
}
userID, err := AddUser(req.Username, req.Passwd, userType)
userID, err := AddUser(req.Username, req.Passwd)
if err != nil {
SendErrorResponse(w, http.StatusInternalServerError, err.Error())
postLog.Error(fmt.Sprintf("[RegisterHandler] Failed to register user \"%s\": %v", req.Username, err))
@@ -118,6 +99,11 @@ func LoginHandler(w http.ResponseWriter, r *http.Request) {
return
}
if !ValidateTimeStamp(r.Header) {
SendErrorResponse(w, http.StatusBadRequest, "Invalid or missing X-Timestamp in header")
return
}
body, err := io.ReadAll(r.Body)
if err != nil {
SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
@@ -139,12 +125,6 @@ func LoginHandler(w http.ResponseWriter, r *http.Request) {
return
}
if err := ValidateTimeStamp(req.TimeStamp); err != nil {
SendErrorResponse(w, http.StatusBadRequest, err.Error())
postLog.Warning(fmt.Sprintf("[LoginHandler] User \"%s\" Login failed: invalid timestamp \"%d\"", req.Username, req.TimeStamp))
return
}
if !isValidInput(req.Username) || !isValidInput(req.Passwd) {
SendErrorResponse(w, http.StatusBadRequest, "Invalid input: contains illegal characters")
postLog.Debug(fmt.Sprintf("[LoginHandler] Login failed: username or password contains illegal characters \"%s\":\"%s\"", req.Username, req.Passwd))
@@ -218,7 +198,7 @@ func SendSuccessResponse(w http.ResponseWriter, message string, data interface{}
w.Write(jsonResp)
}
func ValidateRequest(w http.ResponseWriter, r *http.Request, requiredFields ...string) (int, string, error) {
func ValidateRequest(w http.ResponseWriter, r *http.Request, requiredFields ...string) (int, string, error) { // ValidateRequest validates the request body and header
body, err := io.ReadAll(r.Body)
if err != nil {
return 0, "", fmt.Errorf("Failed to read request body: %w", err)
@@ -234,20 +214,13 @@ func ValidateRequestWithBody(w http.ResponseWriter, r *http.Request, body []byte
return 0, "", fmt.Errorf("Invalid request format: %w", err)
}
token, ok := reqMap["token"].(string)
if !ok || token == "" {
return 0, "", fmt.Errorf("Token is required: %s", token)
token := r.Header.Get("X-Token")
if token == "" {
return 0, "", fmt.Errorf("Token is required in header: %s", token)
}
timeStamp := int64(0)
if ts, ok := reqMap["timeStamp"].(float64); ok {
timeStamp = int64(ts)
} else if !globalConfig.Debug {
return 0, "", fmt.Errorf("Timestamp is required: %d", timeStamp)
}
if err := ValidateTimeStamp(timeStamp); err != nil {
return 0, "", fmt.Errorf("Invalid timestamp: %w", err)
if !ValidateTimeStamp(r.Header) {
return 0, "", fmt.Errorf("Invalid or missing X-Timestamp in header")
}
userID, err := extractUserIDFromToken(token)
@@ -274,20 +247,8 @@ func ValidateRequestWithHeader(w http.ResponseWriter, r *http.Request, requiredF
return 0, "", fmt.Errorf("Token is required in header: %s", token)
}
timeStampStr := r.Header.Get("X-Timestamp")
timeStamp := int64(0)
if timeStampStr != "" {
var err error
timeStamp, err = strconv.ParseInt(timeStampStr, 10, 64)
if err != nil {
return 0, "", fmt.Errorf("Invalid timestamp format in header: %w", err)
}
} else if !globalConfig.Debug {
return 0, "", fmt.Errorf("Timestamp is required in header: %s", timeStampStr)
}
if err := ValidateTimeStamp(timeStamp); err != nil {
return 0, "", err
if !ValidateTimeStamp(r.Header) {
return 0, "", fmt.Errorf("Invalid or missing X-Timestamp in header")
}
userID, err := extractUserIDFromToken(token)