golang实现Branca令牌规范的插件库brancaspecification implementation的使用

Golang实现Branca令牌规范的插件库branca使用指南

简介

branca.go是Branca令牌规范的Go语言实现,适用于Go 1.23+版本。

主要特点和优势:

  • 纯Go实现
  • 无任何第三方依赖
  • 100%代码覆盖率
  • 包含模糊测试

安装

确保您有一个可用的Go 1.23+工作环境,然后执行:

go get -u github.com/essentialkaos/branca/v2

使用示例

基本用法

package main

import (
  "fmt"
  
  "github.com/essentialkaos/branca/v2"
)

func main() {
  // 32字节的密钥
  key := "abcd1234abcd1234abcd1234abcd1234"
  
  // 创建Branca实例
  brc, err := branca.NewBranca([]byte(key))

  if err != nil {
    fmt.Printf("Error: %v\n", err)
    return
  }

  // 要编码的数据
  payload := "MySuperSecretData"
  
  // 编码为令牌字符串
  token, err := brc.EncodeToString([]byte(payload))

  if err != nil {
    fmt.Printf("Error: %v\n", err)
    return
  }

  fmt.Printf("Token: %s\n", token)
}

完整示例(包含编码和解码)

package main

import (
	"fmt"
	"log"

	"github.com/essentialkaos/branca/v2"
)

func main() {
	// 32字节的密钥
	key := "supersecretkeyyoushouldnotcommit"

	// 创建Branca实例
	brc, err := branca.NewBranca([]byte(key))
	if err != nil {
		log.Fatalf("Error creating branca instance: %v", err)
	}

	// 要编码的数据
	payload := "Sensitive user data or any other information"

	// 编码为令牌
	token, err := brc.EncodeToString([]byte(payload))
	if err != nil {
		log.Fatalf("Error encoding token: %v", err)
	}

	fmt.Printf("Generated Token: %s\n", token)

	// 解码令牌
	decoded, err := brc.DecodeToString(token)
	if err != nil {
		log.Fatalf("Error decoding token: %v", err)
	}

	fmt.Printf("Decoded Payload: %s\n", decoded)
}

基准测试

基准测试结果(在Go 1.23.2 Linux/amd64环境下):

BrancaSuite.BenchmarkBase62Decoding            1000000   1106 ns/op   408 B/op    7 allocs/op
BrancaSuite.BenchmarkBase62Encoding            1000000   1105 ns/op   512 B/op    6 allocs/op
BrancaSuite.BenchmarkBrancaDecoding            5000000    421 ns/op    48 B/op    2 allocs/op
BrancaSuite.BenchmarkBrancaDecodingFromString  1000000   1632 ns/op   456 B/op    9 allocs/op
BrancaSuite.BenchmarkBrancaEncoding            1000000   2108 ns/op   152 B/op    4 allocs/op
BrancaSuite.BenchmarkBrancaEncodingToString     500000   3854 ns/op   664 B/op   10 allocs/op

您可以使用make benchmark命令自己运行基准测试。

构建状态

分支 状态
master CI通过
develop CI通过

贡献指南

在向本项目贡献代码前,请阅读我们的贡献指南。

许可证

Apache License, Version 2.0


更多关于golang实现Branca令牌规范的插件库brancaspecification implementation的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang实现Branca令牌规范的插件库brancaspecification implementation的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用Golang实现Branca令牌规范的插件库

Branca是一种安全的令牌格式,基于Fernet规范但使用更现代的加密算法(IETF XChaCha20-Poly1305 AEAD)。下面我将介绍如何在Go中使用branca库实现Branca令牌的创建和验证。

安装branca库

首先安装branca的Go实现库:

go get github.com/hako/branca

基本用法示例

package main

import (
	"fmt"
	"time"

	"github.com/hako/branca"
)

func main() {
	// 1. 创建Branca令牌
	// 密钥必须是32字节长
	key := "supersecretkeyyoushouldnotcommit" // 32字节
	b, err := branca.NewBranca(key)
	if err != nil {
		panic(err)
	}

	// 设置令牌的TTL(可选)
	b.SetTTL(3600) // 1小时过期

	// 编码/创建令牌
	payload := "{\"user_id\":12345,\"role\":\"admin\"}"
	token, err := b.EncodeToString(payload)
	if err != nil {
		panic(err)
	}
	fmt.Println("生成的Branca令牌:", token)

	// 2. 解码/验证令牌
	decodedPayload, err := b.DecodeToString(token)
	if err != nil {
		panic(err)
	}
	fmt.Println("解码后的内容:", decodedPayload)

	// 3. 处理过期令牌
	// 创建一个很快过期的令牌进行测试
	b.SetTTL(1) // 1秒过期
	expiringToken, err := b.EncodeToString(payload)
	if err != nil {
		panic(err)
	}

	time.Sleep(2 * time.Second) // 等待令牌过期

	_, err = b.DecodeToString(expiringToken)
	if err != nil {
		fmt.Println("令牌已过期:", err)
	}
}

高级用法

使用结构体作为payload

type UserClaims struct {
	UserID int    `json:"user_id"`
	Role   string `json:"role"`
	Email  string `json:"email"`
}

func main() {
	key := "supersecretkeyyoushouldnotcommit"
	b, _ := branca.NewBranca(key)

	// 编码结构体
	claims := UserClaims{
		UserID: 12345,
		Role:   "admin",
		Email:  "user@example.com",
	}

	token, err := b.Encode(claims) // 自动JSON编码
	if err != nil {
		panic(err)
	}

	// 解码到结构体
	var decodedClaims UserClaims
	err = b.Decode(token, &decodedClaims)
	if err != nil {
		panic(err)
	}
	fmt.Printf("解码后的结构体: %+v\n", decodedClaims)
}

自定义时间戳

func main() {
	key := "supersecretkeyyoushouldnotcommit"
	b, _ := branca.NewBranca(key)

	// 使用自定义时间戳(Unix时间)
	customTime := time.Now().Add(-30 * time.Minute).Unix()
	token, err := b.EncodeToStringWithTimestamp("payload", customTime)
	if err != nil {
		panic(err)
	}

	// 解码时会检查时间戳是否有效(根据TTL设置)
	_, err = b.DecodeToString(token)
	if err != nil {
		fmt.Println("可能已过期:", err)
	}
}

最佳实践

  1. 密钥管理:永远不要将密钥硬编码在代码中,使用环境变量或密钥管理系统
  2. TTL设置:根据使用场景设置合理的TTL(生存时间)
  3. 错误处理:总是检查解码时的错误,可能的原因包括:
    • 令牌过期
    • 令牌被篡改
    • 密钥不匹配
  4. payload大小:Branca令牌有大小限制,不适合存储大量数据

与其他库的比较

Branca相比JWT有以下优势:

  • 更小的令牌体积
  • 更简单的规范
  • 默认使用更现代的加密算法(XChaCha20-Poly1305)
  • 内置时间戳和过期处理

这个branca库是Go中最流行的Branca实现之一,API设计简洁,性能良好,适合大多数需要安全令牌的场景。

回到顶部