golang实现Branca令牌规范的加密认证插件库branca的使用

Golang实现Branca令牌规范的加密认证插件库branca的使用

简介

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

主要特点和优势:

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

安装

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

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

使用示例

下面是一个完整的示例,展示如何使用branca库生成和验证令牌:

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)
  
  // 验证并解码令牌
  decoded, err := brc.DecodeToString(token)
  
  if err != nil {
    fmt.Printf("Error: %v\n", err)
    return
  }
  
  fmt.Printf("Decoded: %s\n", decoded)
}

完整示例DEMO

package main

import (
	"fmt"
	"log"
	"time"

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

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

	// 初始化Branca
	brc, err := branca.NewBranca([]byte(key))
	if err != nil {
		log.Fatalf("Branca初始化失败: %v", err)
	}

	// 设置令牌有效期(可选)
	brc.SetTTL(3600) // 1小时有效期

	// 要加密的数据
	payload := struct {
		UserID int    `json:"user_id"`
		Role   string `json:"role"`
	}{
		UserID: 12345,
		Role:   "admin",
	}

	// 将结构体编码为JSON
	payloadBytes, err := json.Marshal(payload)
	if err != nil {
		log.Fatalf("JSON编码失败: %v", err)
	}

	// 生成令牌
	token, err := brc.EncodeToString(payloadBytes)
	if err != nil {
		log.Fatalf("令牌生成失败: %v", err)
	}

	fmt.Printf("生成的令牌: %s\n", token)

	// 验证和解码令牌
	decodedBytes, err := brc.DecodeToString(token)
	if err != nil {
		log.Fatalf("令牌验证失败: %v", err)
	}

	fmt.Printf("解码后的数据: %s\n", decodedBytes)

	// 检查令牌是否过期
	_, err = brc.Decode(token)
	if err != nil {
		if err == branca.ErrExpiredToken {
			fmt.Println("令牌已过期")
		} else {
			fmt.Printf("令牌验证错误: %v\n", err)
		}
	}
}

性能基准

以下是该库的性能基准测试结果:

go version go1.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

构建状态

Branch Status
master CI通过
develop CI通过

许可证

Apache License, Version 2.0


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

1 回复

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


Golang实现Branca令牌的加密认证

Branca是一种现代化的安全令牌格式,它基于IETF XChaCha20-Poly1305 AEAD构造,提供了一种简单而安全的方式来生成和验证令牌。下面我将介绍如何在Golang中使用branca库来实现Branca令牌的加密认证。

Branca简介

Branca令牌具有以下特点:

  • 使用XChaCha20-Poly1305进行加密认证
  • 紧凑的二进制格式
  • 包含时间戳以支持过期检查
  • 结构化载荷(通常为JSON)

安装branca库

首先安装branca的Go实现库:

go get github.com/hako/branca

基本用法示例

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"time"

	"github.com/hako/branca"
)

func main() {
	// 1. 创建一个新的Branca实例,需要32字节的密钥
	key := "supersecretkeyyoushouldnotcommit" // 32字节密钥
	bc := branca.NewBranca(key)

	// 2. 准备要编码的数据
	type Payload struct {
		UserID int    `json:"user_id"`
		Name   string `json:"name"`
		Role   string `json:"role"`
	}

	payload := Payload{
		UserID: 12345,
		Name:   "John Doe",
		Role:   "admin",
	}

	// 3. 将数据编码为JSON
	payloadBytes, err := json.Marshal(payload)
	if err != nil {
		log.Fatal(err)
	}

	// 4. 编码为Branca令牌
	token, err := bc.EncodeToString(payloadBytes)
	if err != nil {
		log.Fatal(err)
	}

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

	// 5. 解码令牌
	decoded, err := bc.DecodeToString(token)
	if err != nil {
		log.Fatal(err)
	}

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

	// 6. 验证令牌是否过期(例如60秒内有效)
	_, err = bc.DecodeWithTimeout(token, 60*time.Second)
	if err != nil {
		log.Fatal("Token is expired or invalid: ", err)
	}
	fmt.Println("Token is valid and not expired")
}

高级用法

自定义TTL(生存时间)

// 设置令牌的TTL为1小时
bc.SetTTL(3600)

// 编码时会自动检查TTL
token, err := bc.EncodeToString(payloadBytes)
if err != nil {
    log.Fatal(err)
}

直接处理二进制数据

// 编码为二进制令牌
binaryToken, err := bc.Encode(payloadBytes)
if err != nil {
    log.Fatal(err)
}

// 解码二进制令牌
decodedPayload, err := bc.Decode(binaryToken)
if err != nil {
    log.Fatal(err)
}

处理令牌元数据

// 解码并获取元数据(包括时间戳)
decoded, timestamp, err := bc.DecodeWithTimestamp(token)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Token was created at: %v\n", timestamp)
fmt.Printf("Payload: %s\n", decoded)

实际应用场景示例

// 认证中间件示例
func authMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        token := r.Header.Get("Authorization")
        if token == "" {
            http.Error(w, "Unauthorized", http.StatusUnauthorized)
            return
        }

        // 移除"Bearer "前缀(如果存在)
        if len(token) > 7 && strings.ToUpper(token[0:7]) == "BEARER " {
            token = token[7:]
        }

        // 解码令牌
        payload, err := bc.DecodeToString(token)
        if err != nil {
            http.Error(w, "Invalid token", http.StatusUnauthorized)
            return
        }

        // 将用户信息添加到上下文中
        ctx := context.WithValue(r.Context(), "user", payload)
        next.ServeHTTP(w, r.WithContext(ctx))
    })
}

注意事项

  1. 密钥安全:确保密钥安全存储,不要硬编码在代码中
  2. 密钥长度:必须是32字节
  3. 令牌过期:始终验证令牌的TTL
  4. 错误处理:妥善处理解码错误(无效令牌、过期令牌等)
  5. 性能:Branca操作是CPU密集型的,在高并发场景下可能需要考虑性能影响

Branca提供了一种简单而安全的方式来处理认证令牌,特别适合微服务架构或需要安全传输数据的场景。相比JWT,它提供了更好的安全性和更紧凑的格式。

回到顶部