Golang实现:动态传递用户名密码JSON请求体调用Post API获取JWT
改进方案:动态获取用户信息请求JWT令牌
核心改进思路
- 定义请求体结构体替代硬编码JSON字符串,实现动态赋值
- 重构认证函数,通过参数接收用户登录信息,返回令牌与错误,避免全局变量污染
- 添加HTTP登录接口,适配多用户Web应用场景,接收客户端传入的用户信息
- 完善错误处理逻辑,替换废弃的标准库API
改进后完整代码
package main import ( "bytes" "encoding/json" "fmt" "io" "log" "net/http" "os" "github.com/joho/godotenv" ) // 登录请求结构体,对应认证API所需的参数字段 type LoginRequest struct { Name string `json:"name"` Pwd string `json:"pwd"` HName string `json:"hName"` } // 认证响应结构体,解析API返回的令牌数据 type AuthorizationResponse struct { AuthorizationToken string `json:"authorizationToken"` ExpiresTimestamp string `json:"expiresTimestamp"` } func main() { // 加载环境变量 if err := godotenv.Load(".env"); err != nil { log.Fatalf("加载.env文件失败: %v", err) } // 注册登录接口,供客户端调用 http.HandleFunc("/login", loginHandler) log.Println("服务启动,监听端口8080") if err := http.ListenAndServe(":8080", nil); err != nil { log.Fatalf("服务启动失败: %v", err) } } // 登录接口处理函数,接收客户端提交的用户信息 func loginHandler(w http.ResponseWriter, r *http.Request) { // 仅允许POST请求 if r.Method != http.MethodPost { http.Error(w, "仅支持POST请求", http.StatusMethodNotAllowed) return } // 解析客户端传入的登录参数 var req LoginRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, "请求体解析失败: "+err.Error(), http.StatusBadRequest) return } defer r.Body.Close() // 调用认证接口获取JWT令牌 token, err := getAuthToken(req) if err != nil { http.Error(w, "获取令牌失败: "+err.Error(), http.StatusInternalServerError) return } // 将令牌返回给客户端 w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]string{"token": token}) } // 重构后的认证函数,动态接收用户信息并返回令牌 func getAuthToken(loginReq LoginRequest) (string, error) { authURL := os.Getenv("authorizationUrl") if authURL == "" { return "", fmt.Errorf("authorizationUrl环境变量未配置") } // 将登录参数序列化为JSON请求体 requestBody, err := json.Marshal(loginReq) if err != nil { return "", fmt.Errorf("序列化请求体失败: %v", err) } // 发送POST请求到认证API resp, err := http.Post(authURL, "application/json", io.NopCloser(bytes.NewBuffer(requestBody))) if err != nil { return "", fmt.Errorf("发送认证请求失败: %v", err) } defer resp.Body.Close() // 检查响应状态码是否正常 if resp.StatusCode != http.StatusOK { body, _ := io.ReadAll(resp.Body) return "", fmt.Errorf("认证接口返回错误状态码: %d,响应内容: %s", resp.StatusCode, string(body)) } // 读取并解析响应体 content, err := io.ReadAll(resp.Body) if err != nil { return "", fmt.Errorf("读取响应体失败: %v", err) } var authResp AuthorizationResponse if err := json.Unmarshal(content, &authResp); err != nil { return "", fmt.Errorf("解析认证响应失败: %v", err) } if authResp.AuthorizationToken == "" { return "", fmt.Errorf("认证接口未返回有效令牌") } return authResp.AuthorizationToken, nil }
关键改动说明
- 请求体结构化:新增
LoginRequest结构体,把硬编码的JSON字段映射为Go结构体字段,支持动态传入不同用户的登录信息。 - 函数解耦:
getAuthToken不再依赖全局变量,通过参数接收用户信息并返回令牌与错误,每个请求独立处理,适配多用户并发场景。 - Web场景适配:添加
loginHandler作为HTTP接口,客户端可通过POST请求提交用户名密码,接口完成认证后返回JWT令牌,符合Web应用的使用逻辑。 - 错误处理强化:完善了环境变量校验、HTTP响应状态码检查、序列化/反序列化错误捕获,避免静默失败,便于问题排查。
- 废弃API替换:将已废弃的
ioutil.ReadAll替换为标准库的io.ReadAll,符合Go最新版本的API规范。
内容的提问来源于stack exchange,提问作者user12396077
相关产品推荐
相关产品推荐

