golang实现ID类型哈希编解码安全传输插件库hide的使用
Golang实现ID类型哈希编解码安全传输插件库hide的使用
Hide是一个简单的Go语言包,提供了一种ID类型,可以在编解码时转换为哈希字符串。这样可以避免将技术性ID直接发送给客户端,在API层进行转换。
安装
go get github.com/emvi/hide/v2
使用示例
基本用法
考虑以下用户结构体:
type User struct {
Id int64 `json:"id"`
Username string `json:"username"`
}
当将这个结构体编码为JSON时,ID会以数字形式显示:
{
"id": 123,
"username": "foobar"
}
这会将技术性用户ID暴露给客户端。通过使用hide.ID
类型,可以得到更好的结果:
type User struct {
Id hide.ID `json:"id"`
Username string `json:"username"`
}
现在JSON输出会变成:
{
"id": "beJarVNaQM",
"username": "foobar"
}
完整示例
package main
import (
"encoding/json"
"fmt"
"github.com/emvi/hide"
)
// 定义用户结构体
type User struct {
Id hide.ID `json:"id"`
Username string `json:"username"`
}
func main() {
// 创建一个用户实例
user := User{
Id: 123, // 可以直接使用int64值赋值
Username: "foobar",
}
// 编码为JSON
jsonData, err := json.Marshal(user)
if err != nil {
panic(err)
}
fmt.Println("JSON编码结果:", string(jsonData))
// 输出: {"id":"beJarVNaQM","username":"foobar"}
// 解码JSON
var decodedUser User
err = json.Unmarshal(jsonData, &decodedUser)
if err != nil {
panic(err)
}
fmt.Println("解码后的ID:", decodedUser.Id)
// 输出: 123 (原始ID值)
// 类型转换示例
// 从hide.ID转换为int64
originalID := int64(user.Id)
fmt.Println("转换为int64:", originalID)
// 从int64转换为hide.ID
var newID hide.ID = 456
fmt.Println("新的hide.ID:", newID)
}
自定义哈希函数
Hide默认使用hashids作为哈希函数,但你可以实现自己的哈希函数:
package main
import (
"github.com/emvi/hide"
)
// 自定义哈希实现
type MyHash struct{}
func (h *MyHash) Encode(id []int64) (string, error) {
// 实现自定义编码逻辑
return "custom_" + fmt.Sprint(id[0]), nil
}
func (h *MyHash) Decode(hash string) ([]int64, error) {
// 实现自定义解码逻辑
idStr := strings.TrimPrefix(hash, "custom_")
id, err := strconv.ParseInt(idStr, 10, 64)
return []int64{id}, err
}
func main() {
// 设置自定义哈希函数
hide.UseHash(&MyHash{})
// 现在所有hide.ID操作都会使用你的自定义哈希函数
}
注意事项
- 值为0的ID在编码为JSON或存储到数据库时会转换为
null
hide.ID
内部实际上是int64
类型,可以安全地进行类型转换- 该库主要用于保护API中的技术性ID不被直接暴露
通过使用hide库,你可以轻松地在API层实现ID的哈希转换,既保护了技术细节,又不影响内部逻辑处理。
更多关于golang实现ID类型哈希编解码安全传输插件库hide的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang实现ID类型哈希编解码安全传输插件库hide的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang实现ID类型哈希编解码安全传输插件库hide的使用
hide
是一个用于安全传输ID类型的Golang库,它通过对ID进行哈希编解码来保护敏感ID不被直接暴露在API或URL中。下面我将详细介绍如何使用这个库。
安装
首先安装hide库:
go get github.com/emvi/hide
基本使用
1. 定义ID类型
package main
import (
"fmt"
"github.com/emvi/hide"
)
type UserID int64
func main() {
// 设置全局盐值(在生产环境中应从安全配置中获取)
hide.SetSalt([]byte("your-secret-salt"))
// 原始ID
originalID := UserID(12345)
// 编码ID
encoded := hide.ToString(originalID)
fmt.Println("Encoded ID:", encoded)
// 解码ID
decoded, err := hide.FromString(encoded)
if err != nil {
panic(err)
}
fmt.Println("Decoded ID:", UserID(decoded))
}
2. 在Web应用中使用
package main
import (
"encoding/json"
"net/http"
"github.com/emvi/hide"
)
type User struct {
ID hide.ID `json:"id"`
Name string `json:"name"`
}
func main() {
hide.SetSalt([]byte("your-secret-salt"))
http.HandleFunc("/user", func(w http.ResponseWriter, r *http.Request) {
// 模拟从数据库获取用户
user := User{
ID: hide.ID(12345), // 实际存储的ID
Name: "John Doe",
}
// 自动将ID编码为哈希字符串
json.NewEncoder(w).Encode(user)
})
http.HandleFunc("/user/", func(w http.ResponseWriter, r *http.Request) {
// 从URL获取哈希ID
hashID := r.URL.Path[len("/user/"):]
// 解码为实际ID
id, err := hide.FromString(hashID)
if err != nil {
http.Error(w, "Invalid ID", http.StatusBadRequest)
return
}
// 使用解码后的ID查询数据库...
_ = id
w.Write([]byte("User found with ID: " + hide.ToString(id)))
})
http.ListenAndServe(":8080", nil)
}
3. 自定义类型集成
package main
import (
"database/sql/driver"
"encoding/json"
"fmt"
"github.com/emvi/hide"
)
// 自定义ID类型
type CustomID hide.ID
// 实现json.Marshaler接口
func (id CustomID) MarshalJSON() ([]byte, error) {
return json.Marshal(hide.ToString(hide.ID(id)))
}
// 实现json.Unmarshaler接口
func (id *CustomID) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
decoded, err := hide.FromString(s)
if err != nil {
return err
}
*id = CustomID(decoded)
return nil
}
// 实现driver.Valuer接口(用于数据库存储)
func (id CustomID) Value() (driver.Value, error) {
return int64(id), nil
}
// 实现sql.Scanner接口(用于数据库读取)
func (id *CustomID) Scan(value interface{}) error {
switch v := value.(type) {
case int64:
*id = CustomID(v)
return nil
case nil:
return nil
default:
return fmt.Errorf("unsupported type: %T", v)
}
}
func main() {
hide.SetSalt([]byte("your-secret-salt"))
id := CustomID(12345)
// JSON编码
jsonData, _ := json.Marshal(struct {
ID CustomID `json:"id"`
}{id})
fmt.Println("JSON:", string(jsonData))
// JSON解码
var decoded struct {
ID CustomID `json:"id"`
}
_ = json.Unmarshal(jsonData, &decoded)
fmt.Println("Decoded ID:", decoded.ID)
}
高级配置
1. 自定义哈希长度
hide.SetHashLength(10) // 默认是8
2. 使用自定义哈希函数
hide.SetHashFunc(func(id hide.ID, salt []byte) string {
// 实现自定义哈希逻辑
return customHashFunction(id, salt)
})
3. 验证哈希ID
isValid := hide.IsHash("aBcDeF12") // 检查字符串是否符合哈希格式
安全注意事项
-
盐值管理:
- 盐值应该足够复杂且保密
- 生产环境中应从安全配置中获取,不要硬编码在代码中
- 更改盐值会使之前生成的哈希ID失效
-
哈希强度:
- 默认使用SHA256哈希算法
- 可以通过
SetHashFunc
使用更强的哈希算法
-
ID范围:
- 支持的最大ID值为
1<<53-1
(JavaScript安全整数范围) - 超出此范围的ID可能导致精度丢失
- 支持的最大ID值为
hide
库提供了一种简单有效的方式来保护你的ID不被直接暴露,特别适合REST API开发。通过哈希转换,客户端只能看到无意义的字符串,而服务器可以安全地将其转换回原始ID。