第38讲 返回封装+MD5加密
本讲基于视频实际讲解内容整理
一、本讲概述
前面每个接口都手写 gin.H{"code":..,"msg":..,"data":..},重复且容易不一致。本讲做两件事:统一返回封装(抽一个响应函数)和MD5 密码加密(让注册/登录的密码不以明文存储)。
二、统一返回封装
2.1 定义响应结构
Go
// common/response.go
package common
type Response struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data interface{} `json:"data"`
}
func Success(msg string, data interface{}) Response {
return Response{Code: 200, Msg: msg, Data: data}
}
func Fail(code int, msg string) Response {
return Response{Code: code, Msg: msg, Data: nil}
}
2.2 在 handler 中使用
Go
func Register(c *gin.Context) {
// ...校验逻辑...
if err := DB.Create(&user).Error; err != nil {
c.JSON(200, common.Fail(500, "注册失败"))
return
}
c.JSON(200, common.Success("注册成功", gin.H{"redirect": "/login"}))
}
老师强调:封装后所有接口返回结构一致,前端处理更省心。这也呼应第33讲提到的"统一返回"。把响应函数放
common包,全局复用。
三、MD5 加密
3.1 为什么加密
密码明文存库,一旦数据库泄露,所有账号都危险。至少要做哈希(本讲用 MD5 演示,生产推荐 bcrypt)。
3.2 Go 实现 MD5
Go
import (
"crypto/md5"
"encoding/hex"
)
func Md5(str string) string {
h := md5.Sum([]byte(str))
return hex.EncodeToString(h[:])
}
md5.Sum返回[16]byte,hex.EncodeToString转成 32 位十六进制字符串,这就是常见的 MD5 值。
3.3 注册/登录使用 MD5
Go
// 注册时加密存储
user := User{Username: username, Password: Md5(password)}
// 登录时把输入也加密再比对
var u User
DB.Where("username = ?", username).First(&u)
if u.Password != Md5(inputPassword) {
c.JSON(200, common.Fail(400, "密码错误"))
return
}
老师提醒:注册和登录必须用同一个加密方式,否则存的密文和输入的密文对不上。本讲用 MD5 演示原理,实际项目建议用
bcrypt(加盐、抗暴力破解更强)。
四、加盐(进阶了解)
单纯 MD5 容易被彩虹表反查。可加盐提升安全性:
Go
const salt = "bbs_salt_2026"
func Md5WithSalt(str string) string {
return Md5(str + salt)
}
五、本讲小结
| 知识点 | 要点 |
|---|---|
| 响应封装 | 定义 Response + Success/Fail 函数 |
| 复用 | 放 common 包,全局调用 |
| MD5 | md5.Sum + hex.EncodeToString |
| 注册加密 | 存 Md5(password) |
| 登录比对 | 输入也 Md5 后比较 |
| 加盐 | 拼接固定盐值,提升安全 |
六、课后练习
- 在
common包定义Response结构和Success/Fail函数 - 把之前写的登录、注册接口改成用统一封装返回
- 实现
Md5函数,对字符串加密并验证输出长度 32 - 注册时用
Md5(password)存储密码 - 登录时把输入密码
Md5后与库内密文比对 - 了解
bcrypt与 MD5 的区别,思考为什么生产环境不推荐纯 MD5