当前位置: 首页 > article >正文

golang 后端验证码 模拟接口 post get ,postman测试

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"math/rand"
	"net/http"
	"sync"
	"time"
)

// 定义结构体
type SMSRequest struct {
	UID string `json:"uid"`
}

type SMSResponse struct {
	Code       int    `json:"code"`
	Message    string `json:"message"`
	VerifyCode string `json:"verifyCode"`
}

type EmailResponse struct {
	Code int `json:"code"`
	Data struct {
		Email string `json:"email"`
	} `json:"data"`
}

type ExportDataRequest struct {
	UID        string `json:"uid"`
	ChannelID  string `json:"channelId"`
	Month      int    `json:"month"`
	Nick       string `json:"nick"`
	Receiver   string `json:"receiver"`
	VerifyCode string `json:"verifyCode"`
}

type TableData struct {
	Key           int    `json:"key"`
	Month         int    `json:"month"`
	HostUid       int    `json:"hostUid"`
	Nick          string `json:"nick"`
	HuyaId        string `json:"huyaId"`
	LiveDayCnt    int    `json:"liveDayCnt"`
	LiveDayStatus int    `json:"liveDayStatus"`
	HostGain      int    `json:"hostGain"`
}

type ExportDataResponse struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Data    struct {
		Status   string      `json:"status"`
		DataList []TableData `json:"dataList"`
	} `json:"data"`
}

// 全局变量用于保存验证码
var (
	verificationCodes = make(map[string]string)
	mutex             sync.Mutex
)

func generateCode() string {
	rand.Seed(time.Now().UnixNano())
	return fmt.Sprintf("%06d", rand.Intn(1000000))
}

func main() {
	fmt.Println("Registering route /api/getSmsCode")
	http.HandleFunc("/api/getSmsCode", getSmsCodeHandler)

	fmt.Println("Registering route /api/getLastEmail")
	http.HandleFunc("/api/getLastEmail", getLastEmailHandler)

	fmt.Println("Registering route /api/exportData")
	http.HandleFunc("/api/exportData", exportDataHandler)

	log.Println("Server starting on port 8080...")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatalf("Server failed to start: %v", err)
	}
}

// 处理获取短信验证码请求
func getSmsCodeHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("Received request for /api/getSmsCode")
	if r.Method != http.MethodPost {
		log.Println("Invalid method. Only POST is allowed.")
		httpResponse(w, http.StatusMethodNotAllowed, "Method Not Allowed")
		return
	}

	var req SMSRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		log.Printf("Error decoding SMSRequest: %v\n", err)
		httpResponse(w, http.StatusBadRequest, "Invalid request")
		return
	}

	if req.UID == "" {
		log.Println("UID is missing in the SMSRequest")
		httpResponse(w, http.StatusBadRequest, "UID is required")
		return
	}

	verifyCode := generateCode()
	mutex.Lock()
	verificationCodes[req.UID] = verifyCode
	mutex.Unlock()

	log.Printf("Sending SMS to user %s with VerifyCode %s...\n", req.UID, verifyCode)
	response := SMSResponse{
		Code:       200,
		Message:    "SMS Sent Successfully",
		VerifyCode: verifyCode,
	}
	jsonResponse(w, response)
}

// 处理获取最后一次邮箱请求
func getLastEmailHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("Received request for /api/getLastEmail")
	response := EmailResponse{
		Code: 200,
	}
	response.Data.Email = "user@example.com"
	jsonResponse(w, response)
}

// 处理导出数据请求
func exportDataHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("Received request for /api/exportData")
	if r.Method != http.MethodPost {
		log.Println("Invalid method. Only POST is allowed.")
		httpResponse(w, http.StatusMethodNotAllowed, "Method Not Allowed")
		return
	}

	var req ExportDataRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		log.Printf("Error decoding ExportDataRequest: %v\n", err)
		httpResponse(w, http.StatusBadRequest, "Invalid request")
		return
	}

	log.Printf("Request received: %+v\n", req)

	if req.UID == "" || req.ChannelID == "" || req.Month == 0 || req.Nick == "" || req.Receiver == "" || req.VerifyCode == "" {
		log.Println("Missing fields in ExportDataRequest")
		httpResponse(w, http.StatusBadRequest, "All fields are required")
		return
	}

	mutex.Lock()
	storedVerifyCode, exists := verificationCodes[req.UID]
	mutex.Unlock()

	log.Printf("Stored code: %s, Input code: %s\n", storedVerifyCode, req.VerifyCode)

	if !exists || storedVerifyCode != req.VerifyCode {
		log.Printf("Invalid VerifyCode for user %s\n", req.UID)
		httpResponse(w, http.StatusUnauthorized, "Invalid or expired VerifyCode")
		return
	}

	log.Printf("Exporting data for ChannelID: %s, Month: %d, Nick: %s, Receiver: %s, VerifyCode: %s\n",
		req.ChannelID, req.Month, req.Nick, req.Receiver, req.VerifyCode)

	// 添加返回的表格数据
	tableData := []TableData{
		{Key: 0, Month: 202410, HostUid: 2344, Nick: "PlayerOne0", HuyaId: "huya1234560", LiveDayCnt: 20, LiveDayStatus: 0, HostGain: 1000},
		{Key: 1, Month: 202410, HostUid: 2344, Nick: "PlayerOne1", HuyaId: "huya1234561", LiveDayCnt: 21, LiveDayStatus: 1, HostGain: 1001},
		{Key: 2, Month: 202410, HostUid: 2344, Nick: "PlayerOne2", HuyaId: "huya1234562", LiveDayCnt: 22, LiveDayStatus: 0, HostGain: 1002},
		{Key: 3, Month: 202410, HostUid: 2344, Nick: "PlayerOne3", HuyaId: "huya1234563", LiveDayCnt: 23, LiveDayStatus: 1, HostGain: 1003},
		{Key: 4, Month: 202410, HostUid: 2344, Nick: "PlayerOne4", HuyaId: "huya1234564", LiveDayCnt: 24, LiveDayStatus: 0, HostGain: 1004},
		{Key: 5, Month: 202410, HostUid: 2344, Nick: "PlayerOne5", HuyaId: "huya1234565", LiveDayCnt: 25, LiveDayStatus: 1, HostGain: 1005},
		{Key: 6, Month: 202410, HostUid: 2344, Nick: "PlayerOne6", HuyaId: "huya1234566", LiveDayCnt: 26, LiveDayStatus: 0, HostGain: 1006},
		{Key: 7, Month: 202410, HostUid: 2344, Nick: "PlayerOne7", HuyaId: "huya1234567", LiveDayCnt: 27, LiveDayStatus: 1, HostGain: 1007},
		{Key: 8, Month: 202410, HostUid: 2344, Nick: "PlayerOne8", HuyaId: "huya1234568", LiveDayCnt: 28, LiveDayStatus: 0, HostGain: 1008},
		{Key: 9, Month: 202410, HostUid: 2344, Nick: "PlayerOne9", HuyaId: "huya1234569", LiveDayCnt: 29, LiveDayStatus: 1, HostGain: 1009},
	}

	var response ExportDataResponse
	response.Code = 200
	response.Message = "Export successful"
	response.Data.Status = "Exported"
	response.Data.DataList = tableData

	jsonResponse(w, response)
}

// 发送JSON响应
func jsonResponse(w http.ResponseWriter, data interface{}) {
	w.Header().Set("Content-Type", "application/json")
	if err := json.NewEncoder(w).Encode(data); err != nil {
		log.Printf("Error encoding response: %v\n", err)
		httpResponse(w, http.StatusInternalServerError, "Internal Server Error")
	}
}

// 发送HTTP错误响应
func httpResponse(w http.ResponseWriter, code int, message string) {
	w.WriteHeader(code)
	w.Write([]byte(message))
}

测试请求体示例

确保在 Postman 中设置 Content-Typeapplication/json,并使用以下 JSON 请求体。

获取短信验证码请求 (POST):
  • URL: http://localhost:8080/api/getSmsCode
  • 请求体:
{
    "uid": "123456789"
}

获取最后一次邮箱请求 (GET):
  • URL: http://localhost:8080/api/getLastEmail
  • 无需请求体。
导出数据请求 (POST):
  • URL: http://localhost:8080/api/exportData
  • 请求体:
{
    "uid": "123456789",
    "channelId": "channel123",
    "month": 8,
    "nick": "SampleNick",
    "receiver": "user@example.com",
    "verifyCode": "从getSmsCode返回的verifyCode"
}

 

详细的注释代码的每一行:

package main // 定义包名称

import ( // 导入必要的包
	"encoding/json" // JSON编码和解码
	"fmt"           // 格式化输入输出
	"log"           // 日志记录
	"math/rand"     // 生成随机数
	"net/http"      // HTTP协议实现
	"sync"          // 同步原语(如互斥锁)
	"time"          // 时间操作
)

// SMSRequest 定义请求短信验证码时的数据结构
type SMSRequest struct {
	UID string `json:"uid"` // 用户唯一标识
}

// SMSResponse 定义发送短信后的响应数据结构
type SMSResponse struct {
	Code       int    `json:"code"`       // 响应状态码
	Message    string `json:"message"`    // 响应消息
	VerifyCode string `json:"verifyCode"` // 发送的验证码
}

// EmailResponse 定义请求最后一封邮件信息的响应数据结构
type EmailResponse struct {
	Code int `json:"code"` // 响应状态码
	Data struct {
		Email string `json:"email"` // 邮件地址
	} `json:"data"` // 数据包装对象
}

// ExportDataRequest 定义导出数据请求的数据结构
type ExportDataRequest struct {
	UID        string `json:"uid"`        // 用户唯一标识
	ChannelID  string `json:"channelId"`  // 频道ID
	Month      int    `json:"month"`      // 月份
	Nick       string `json:"nick"`       // 用户昵称
	Receiver   string `json:"receiver"`   // 接收者
	VerifyCode string `json:"verifyCode"` // 验证码
}

// TableData 定义返回的表格数据结构
type TableData struct {
	Key           int    `json:"key"`           // 表格的键
	Month         int    `json:"month"`         // 月份
	HostUid       int    `json:"hostUid"`       // 主播用户ID
	Nick          string `json:"nick"`          // 昵称
	HuyaId        string `json:"huyaId"`        // 虎牙ID
	LiveDayCnt    int    `json:"liveDayCnt"`    // 直播天数
	LiveDayStatus int    `json:"liveDayStatus"` // 直播天数状态
	HostGain      int    `json:"hostGain"`      // 主播收益
}

// ExportDataResponse 定义导出数据响应的数据结构
type ExportDataResponse struct {
	Code    int    `json:"code"`    // 响应状态码
	Message string `json:"message"` // 响应消息
	Data    struct {
		Status   string      `json:"status"`   // 导出状态
		DataList []TableData `json:"dataList"` // 导出的数据列表
	} `json:"data"` // 数据包装对象
}

// 全局变量,用于储存验证码
var (
	verificationCodes = make(map[string]string) // 存储用户ID和对应的验证码
	mutex             sync.Mutex                // 互斥锁,确保验证码的存取安全
)

// 生成验证码的函数
func generateCode() string {
	rand.Seed(time.Now().UnixNano())           // 初始化随机数种子
	return fmt.Sprintf("%06d", rand.Intn(1000000)) // 生成六位随机数作为验证码
}

// main函数,程序入口
func main() {
	fmt.Println("Registering route /api/getSmsCode") // 注册获取短信验证码的路由
	http.HandleFunc("/api/getSmsCode", getSmsCodeHandler) // 设置处理函数

	fmt.Println("Registering route /api/getLastEmail") // 注册获取最后一封邮件的路由
	http.HandleFunc("/api/getLastEmail", getLastEmailHandler) // 设置处理函数

	fmt.Println("Registering route /api/exportData") // 注册导出数据的路由
	http.HandleFunc("/api/exportData", exportDataHandler) // 设置处理函数

	log.Println("Server starting on port 8080...") // 日志记录,服务器开始在8080端口监听
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatalf("Server failed to start: %v", err) // 日志记录,服务器启动失败
	}
}

// 处理短信验证码请求的函数
func getSmsCodeHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("Received request for /api/getSmsCode") // 日志记录,接收到请求
	if r.Method != http.MethodPost {                    // 检查请求方法是否为POST
		log.Println("Invalid method. Only POST is allowed.") // 日志记录,请求方法不合法
		httpResponse(w, http.StatusMethodNotAllowed, "Method Not Allowed") // 响应405状态码
		return
	}

	var req SMSRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil { // 解析请求体
		log.Printf("Error decoding SMSRequest: %v", err) // 日志记录,解析错误
		httpResponse(w, http.StatusBadRequest, "Invalid request") // 响应400状态码
		return
	}

	if req.UID == "" { // 检查UID是否为空
		log.Println("UID is missing in the SMSRequest") // 日志记录,UID缺失
		httpResponse(w, http.StatusBadRequest, "UID is required") // 响应400状态码
		return
	}

	verifyCode := generateCode() // 生成验证码
	mutex.Lock()                 // 加锁
	verificationCodes[req.UID] = verifyCode // 存储验证码
	mutex.Unlock()               // 解锁

	log.Printf("Sending SMS to user %s with VerifyCode %s...", req.UID, verifyCode) // 日志记录,发送短信
	response := SMSResponse{ // 构造响应对象
		Code:       200,
		Message:    "SMS Sent Successfully", // 响应成功信息
		VerifyCode: verifyCode, // 包含验证码
	}
	jsonResponse(w, response) // 发送JSON响应
}

// 处理获取最后一封电子邮件的函数
func getLastEmailHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("Received request for /api/getLastEmail") // 日志记录,接收到请求
	response := EmailResponse{ // 构造响应对象
		Code: 200,
	}
	response.Data.Email = "user@example.com" // 设置电子邮件地址
	jsonResponse(w, response) // 发送JSON响应
}

// 处理导出数据请求的函数
func exportDataHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("Received request for /api/exportData") // 日志记录,接收到请求
	if r.Method != http.MethodPost { // 检查请求方法是否为POST
		log.Println("Invalid method. Only POST is allowed.") // 日志记录,请求方法不合法
		httpResponse(w, http.StatusMethodNotAllowed, "Method Not Allowed") // 响应405状态码
		return
	}

	var req ExportDataRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil { // 解析请求体
		log.Printf("Error decoding ExportDataRequest: %v", err) // 日志记录,解析错误
		httpResponse(w, http.StatusBadRequest, "Invalid request") // 响应400状态码
		return
	}

	log.Printf("Request received: %+v", req) // 日志记录,显示请求内容

	if req.UID == "" || req.ChannelID == "" || req.Month == 0 || req.Nick == "" || req.Receiver == "" || req.VerifyCode == "" { // 检查字段完整性
		log.Println("Missing fields in ExportDataRequest") // 日志记录,缺少字段
		httpResponse(w, http.StatusBadRequest, "All fields are required") // 响应400状态码
		return
	}

	mutex.Lock() // 加锁
	storedVerifyCode, exists := verificationCodes[req.UID] // 获取存储的验证码
	mutex.Unlock() // 解锁

	log.Printf("Stored code: %s, Input code: %s", storedVerifyCode, req.VerifyCode) // 日志记录,显示验证码比对信息

	if !exists || storedVerifyCode != req.VerifyCode { // 验证验证码
		log.Printf("Invalid VerifyCode for user %s", req.UID) // 日志记录,验证码无效
		httpResponse(w, http.StatusUnauthorized, "Invalid or expired VerifyCode") // 响应401状态码
		return
	}

	log.Printf("Exporting data for ChannelID: %s, Month: %d, Nick: %s, Receiver: %s, VerifyCode: %s", req.ChannelID, req.Month, req.Nick, req.Receiver, req.VerifyCode) // 日志记录,导出数据详情

	// 模拟的数据,实际应用中应从数据库或其他存储中获取
	tableData := []TableData{ // 构造表数据
		{Key: 0, Month: 202410, HostUid: 2344, Nick: "PlayerOne0", HuyaId: "huya1234560", LiveDayCnt: 20, LiveDayStatus: 0, HostGain: 1000},
		{Key: 1, Month: 202410, HostUid: 2344, Nick: "PlayerOne1", HuyaId: "huya1234561", LiveDayCnt: 21, LiveDayStatus: 1, HostGain: 1001},
		{Key: 2, Month: 202410, HostUid: 2344, Nick: "PlayerOne2", HuyaId: "huya1234562", LiveDayCnt: 22, LiveDayStatus: 0, HostGain: 1002},
		{Key: 3, Month: 202410, HostUid: 2344, Nick: "PlayerOne3", HuyaId: "huya1234563", LiveDayCnt: 23, LiveDayStatus: 1, HostGain: 1003},
		{Key: 4, Month: 202410, HostUid: 2344, Nick: "PlayerOne4", HuyaId: "huya1234564", LiveDayCnt: 24, LiveDayStatus: 0, HostGain: 1004},
		{Key: 5, Month: 202410, HostUid: 2344, Nick: "PlayerOne5", HuyaId: "huya1234565", LiveDayCnt: 25, LiveDayStatus: 1, HostGain: 1005},
		{Key: 6, Month: 202410, HostUid: 2344, Nick: "PlayerOne6", HuyaId: "huya1234566", LiveDayCnt: 26, LiveDayStatus: 0, HostGain: 1006},
		{Key: 7, Month: 202410, HostUid: 2344, Nick: "PlayerOne7", HuyaId: "huya1234567", LiveDayCnt: 27, LiveDayStatus: 1, HostGain: 1007},
		{Key: 8, Month: 202410, HostUid: 2344, Nick: "PlayerOne8", HuyaId: "huya1234568", LiveDayCnt: 28, LiveDayStatus: 0, HostGain: 1008},
		{Key: 9, Month: 202410, HostUid: 2344, Nick: "PlayerOne9", HuyaId: "huya1234569", LiveDayCnt: 29, LiveDayStatus: 1, HostGain: 1009},
	}

	var response ExportDataResponse // 构造响应对象
	response.Code = 200
	response.Message = "Export successful" // 设置成功消息
	response.Data.Status = "Exported"
	response.Data.DataList = tableData // 设置数据列表

	jsonResponse(w, response) // 发送JSON响应
}

// 发送JSON格式响应的函数
func jsonResponse(w http.ResponseWriter, data interface{}) {
	w.Header().Set("Content-Type", "application/json") // 设置响应头
	if err := json.NewEncoder(w).Encode(data); err != nil { // 编码并发送JSON
		log.Printf("Error encoding response: %v", err) // 日志记录,编码错误
		httpResponse(w, http.StatusInternalServerError, "Internal Server Error") // 响应500状态码
	}
}

// 发送HTTP状态响应的函数
func httpResponse(w http.ResponseWriter, code int, message string) {
	w.WriteHeader(code) // 设置状态码
	w.Write([]byte(message)) // 发送响应消息
}


http://www.kler.cn/a/370994.html

相关文章:

  • 洛谷 P4251 [SCOI2015] 小凸玩矩阵
  • python实战项目49:足彩开奖竞猜数据抓取
  • uni-app如何接收uni.$emit()里面传递的内容
  • 【AI试衣整合包及教程】CatVTON带你进入AI换装新时代
  • SpringBoot实现 License 认证(只校验有效期)
  • 三维测量与建模笔记 - 2.1 坐标转换基础
  • 一款强大的开源OCR工具,支持90+语言识别
  • vmware运维技巧总结
  • 倪师学习笔记-天纪-易经八卦
  • Axure设计之多级菜单导航教程(中继器)
  • 好用的idea插件之自动sql生成
  • 详细指南:解决Garmin 手表无法与电脑连接的问题
  • 15分钟学 Go 第 25 天:使用WaitGroup
  • 【计网】UDP Echo Server与Client实战:从零开始构建简单通信回显程序
  • 探索Konko AI:快速集成大语言模型的最佳实践
  • Pr 视频效果:闪光灯
  • CodeQL学习笔记(2)-QL语法(递归)
  • 【亲测】mini版centos7.9配置网络基础ssh等直接使用
  • STM32外设应用
  • 2024性价比家居好物有哪些?推荐五款值得每个家庭拥有的好物品牌!