{"record":{"id":"ed4935d65985fba4","repo":"fish2018/pansou","slug":"username-cannot-be-empty","errorCode":null,"errorMessage":"username cannot be empty","messagePattern":"username cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/jwt.go","lineNumber":19,"sourceCode":"package util\n\nimport (\n\t\"errors\"\n\t\"time\"\n\n\t\"github.com/golang-jwt/jwt/v5\"\n)\n\n// Claims JWT载荷结构\ntype Claims struct {\n\tUsername string `json:\"username\"`\n\tjwt.RegisteredClaims\n}\n\n// GenerateToken 生成JWT token\nfunc GenerateToken(username string, secret string, expiry time.Duration) (string, error) {\n\tif username == \"\" {\n\t\treturn \"\", errors.New(\"username cannot be empty\")\n\t}\n\tif secret == \"\" {\n\t\treturn \"\", errors.New(\"secret cannot be empty\")\n\t}\n\n\texpirationTime := time.Now().Add(expiry)\n\tclaims := &Claims{\n\t\tUsername: username,\n\t\tRegisteredClaims: jwt.RegisteredClaims{\n\t\t\tExpiresAt: jwt.NewNumericDate(expirationTime),\n\t\t\tIssuedAt:  jwt.NewNumericDate(time.Now()),\n\t\t\tIssuer:    \"pansou\",\n\t\t},\n\t}\n\n\ttoken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)\n\treturn token.SignedString([]byte(secret))\n}","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/util/jwt.go#L1-L37","documentation":"GenerateToken validates its inputs before signing a JWT: an empty username is rejected because the resulting token would carry no usable identity. It returns a plain sentinel error before any claims are built.","triggerScenarios":"Calling util.GenerateToken(\"\", secret, expiry), typically from LoginHandler when the login request body had an empty/missing username field.","commonSituations":"Client POSTs login JSON without the username field; frontend sends empty string; request binding defaults zero value; DB lookup returned an empty username.","solutions":["Validate the login request body before calling GenerateToken and return 400 for empty username","Check LoginHandler binding: ensure the username field is required (binding:\"required\" on the struct)","Log the incoming request to confirm the field name matches what the client sends"],"exampleFix":"// before\ntoken, err := util.GenerateToken(req.Username, secret, expiry)\n// after\nif strings.TrimSpace(req.Username) == \"\" {\n    c.JSON(400, gin.H{\"error\": \"username is required\"})\n    return\n}\ntoken, err := util.GenerateToken(req.Username, secret, expiry)","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(username) == \"\" { return errors.New(\"username required\") }","typeGuard":null,"tryCatchPattern":"token, err := util.GenerateToken(username, secret, expiry)\nif err != nil {\n    http.Error(w, \"invalid login input\", 400)\n    return\n}","preventionTips":["Mark username required in request binding structs","Trim whitespace before calling GenerateToken","Return 400 for empty login fields"],"tags":["jwt","validation","go","authentication"],"backgroundTag":"empty-required-field","analyzedSha":"beaa56133755a548ebc51b090b3816e2ae044aa6","analyzedAt":"2026-09-07T00:31:18.025Z","contentChangedAt":"2026-09-07T00:31:18.025Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}