English | 简体中文
A collection of commonly used Go utilities for web development (with Hertz-friendly integrations).
go get github.com/kainonly/go| Module | Description |
|---|---|
| vd | Validator wrapper + Hertz integration |
| passport | JWT auth (HS256) |
| csrf | CSRF protection middleware |
| captcha | Captcha management (Redis) |
| locker | Counter & lockout helpers (Redis) |
| passlib | Password hashing (Argon2id) |
| totp | TOTP |
| cipher | Symmetric encryption helpers |
| help | Misc helpers |
import "github.com/kainonly/go/vd"
v := vd.Default()
type User struct {
Name string `vd:"required,snake"`
Phone string `vd:"required,phone"`
}
_ = v.Validate(&User{Name: "user_name", Phone: "13800138000"})import "github.com/kainonly/go/passport"
auth := passport.New(
passport.SetKey("your-secret-key"),
passport.SetIssuer("your-app"),
)
claims := passport.NewClaims()
claims.ID = "user-123"
claims.SetData(map[string]any{"role": "admin"})
token, _ := auth.Create(claims)
_, _ = auth.Verify(token)import "github.com/kainonly/go/csrf"
_ = csrf.New(
csrf.SetKey("your-secret-key"),
csrf.SetDomain("example.com"),
)Wrapper around go-playground/validator with Hertz integration and a set of commonly used rules.
import "github.com/kainonly/go/vd"
v := vd.Default()
v := vd.New(
vd.SetTag("vd"),
vd.SetRules(
vd.Snake(),
vd.Sort(),
vd.Phone(),
vd.IDCard(),
vd.PasswordMedium(),
),
)
type User struct {
Name string `vd:"required,snake"`
Phone string `vd:"required,phone"`
}
err := v.Validate(&User{Name: "user_name", Phone: "13800138000"})
_ = errimport (
"github.com/cloudwego/hertz/pkg/app/server"
"github.com/kainonly/go/vd"
)
func main() {
v := vd.New(vd.SetRules(vd.All()...))
h := server.Default(
server.WithHostPorts(":8080"),
server.WithCustomValidator(v.Engine()),
)
h.Spin()
}| Function | Description |
|---|---|
All() |
All rules |
Common() |
Common rules (snake, sort, phone, idcard, username, slug, password_medium) |
Chinese() |
CN localized rules |
NamingConvention() |
Naming convention rules |
| Rule | Tag | Description | Example |
|---|---|---|---|
Phone() |
phone |
Mobile phone number | 13800138000 |
IDCard() |
idcard |
CN ID card number | 110101199003071234 |
BankCard() |
bankcard |
Bank card number (Luhn) | 6222021234567890 |
LicensePlate() |
license_plate |
License plate | 京A12345 |
USCC() |
uscc |
Unified social credit code | 91310000MA1FL8TQ32 |
ChineseWord() |
chinese |
Chinese-only string | 你好世界 |
ChineseName() |
chinese_name |
Chinese name | 张三 |
TelPhone() |
tel |
Landline phone | 010-12345678 |
QQ() |
qq |
QQ number | 12345678 |
WeChat() |
wechat |
WeChat ID | wxid_abc123 |
ZipCode() |
zipcode |
Postal code | 518000 |
| Rule | Tag | Description |
|---|---|---|
PasswordWeak() |
password_weak |
≥ 6 characters |
PasswordMedium() |
password_medium |
≥ 8 characters; contains letters and digits |
PasswordStrong() |
password_strong |
≥ 8 characters; contains upper+lower+digits+special |
| Rule | Tag | Example |
|---|---|---|
Snake() |
snake |
user_name |
PascalCase() |
pascal |
UserName |
CamelCase() |
camel |
userName |
KebabCase() |
kebab |
user-name |
UpperSnake() |
upper_snake |
USER_NAME |
Variable() |
variable |
_privateVar |
| Rule | Tag | Description |
|---|---|---|
Sort() |
sort |
Sort format: field:1 or field:-1 |
Username() |
username |
Username (3-20 chars) |
Slug() |
slug |
URL slug |
ObjectID() |
objectid |
MongoDB ObjectId |
Snowflake() |
snowflake |
Snowflake ID |
Version() |
version |
Semver like 1.0.0 |
SafeString() |
safe_string |
Injection-safe string |
AlphaNumDash() |
alphanumdash |
Letters, digits, underscore, dash |
Decimal() |
decimal |
Decimal string |
PositiveDecimal() |
positive_decimal |
Positive decimal string |
Domain() |
domain |
Domain |
FileName() |
filename |
File name |
FileExt() |
file_ext |
File extension |
FilePath() |
file_path |
File path |
Color() |
color |
Color without # |
NotBlank() |
notblank |
Non-whitespace string |
v := vd.New(vd.SetRules(
vd.Rule{
Tag: "even",
Fn: func(fl vd.FieldLevel) bool {
return fl.Field().Int()%2 == 0
},
},
))JWT authentication based on HS256.
import "github.com/kainonly/go/passport"
auth := passport.New(
passport.SetKey("your-secret-key"),
passport.SetIssuer("your-app"),
)
claims := passport.NewClaims()
claims.ID = "user-123"
claims.SetData(map[string]any{"role": "admin"})
token, err := auth.Create(claims)
claims, err = auth.Verify(token)
_ = claims
_ = errCSRF middleware using the double-submit cookie approach.
import "github.com/kainonly/go/csrf"
c := csrf.New(
csrf.SetKey("your-secret-key"),
csrf.SetDomain("example.com"),
)
_ = cCaptcha management backed by Redis.
import "github.com/kainonly/go/captcha"
cap := captcha.New(redisClient)
cap.Create(ctx, "login:user123", "123456", 5*time.Minute)
err := cap.Verify(ctx, "login:user123", "123456")
if errors.Is(err, captcha.ErrInvalidCode) {
}
if errors.Is(err, captcha.ErrNotExists) {
}Redis-based counter and lockout helper for scenarios like login failures and rate limiting.
import "github.com/kainonly/go/locker"
lock := locker.New(redisClient)
count, err := lock.Increment(ctx, "login:user123", time.Minute)
_ = count
_ = err
err = lock.Check(ctx, "login:user123", 5)
if errors.Is(err, locker.ErrLocked) {
}
lock.Delete(ctx, "login:user123")Argon2id-based password hashing.
import "github.com/kainonly/go/passlib"
hash, err := passlib.Hash("password123")
_ = err
err = passlib.Verify("password123", hash)
if passlib.NeedsRehash(hash) {
newHash, _ := passlib.Hash("password123")
_ = newHash
}TOTP secret generation and code validation.
import "github.com/kainonly/go/totp"
secret, err := totp.GenerateSecret()
_ = secret
_ = err
valid, err := totp.Validate(code, secret)
_ = valid
_ = errSymmetric encryption helpers.
import "github.com/kainonly/go/cipher"
c := cipher.New(cipher.SetKey("your-32-byte-key"))
encrypted, err := c.Encode(data)
_ = encrypted
_ = err
decrypted, err := c.Decode(encrypted)
_ = decrypted
_ = errMisc helper functions.
import "github.com/kainonly/go/help"
help.Random(16)
help.RandomNumber(6)
help.RandomAlphabet(8)
help.RandomUppercase(8)
help.RandomLowercase(8)help.Uuid7()
help.MustUuid7()
help.Uuid7Time(id)
help.Uuid()
help.SID()Why UUIDv7?
- Time-ordered IDs; new records naturally come later
- Better index locality for databases with sequential inserts
- Extract creation time from the ID
help.Sha256hex(s)
help.HmacSha256(s, key)sig, _ := help.Sm2Sign(privateKey, data)
valid := help.Sm2Verify(publicKey, data, sig)
_ = valid
encrypted, _ := help.SM4Encrypt(key, plaintext)
decrypted, _ := help.SM4Decrypt(key, encrypted)
_ = decryptedhelp.Ptr(value)
help.IsEmpty(value)
help.Reverse(slice)
help.Shuffle(slice)