ginaksk

package module
v1.0.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 10, 2023 License: MIT Imports: 16 Imported by: 0

README

ginaksk 实现 gin 的中间件, 用于认证客户端请求和校验请求内容

godoc

编码格式

ginaksk 默认使用 encoding/hex 生成字符串,添加到 HTTP 请求的头部; 可以在使用 Validate 中间件之前,调用 SetEncoder 修改为其他编码格式,如示例中的 base64

Hash 算法

ginaksk 默认使用 sha256.New 作为 hmac.New 的 hash.Hash 类型; 可以在使用 Validate 中间件之前,调用 SetHash 修改为其他算法,如 sha512.New

HTTP 头部

名称 说明
x-auth-accesskey 客户端的访问密钥
x-auth-timestamp 请求发起时的时间戳,单位: 秒
x-auth-signature 请求的签名
x-auth-body-hash 请求的 Body 的 Hash 值
x-auth-random-str 随机字符串

签名方法

  1. 假设哈希算法为SHA256, 编码格式为HEX;
  2. 取出客户端访问密钥: x-auth-accesskey;
  3. 取当前的时间戳: x-auth-timestamp;
  4. 生成随机字符串: x-auth-random-str;
  5. 如果请求的BODY非空, 对BODY计算SHA256的值, 并编码为HEX得到:x-auth-body-hash;
  6. x-auth-accesskey,x-auth-timestamp,x-auth-random-str,x-auth-body-hash 按照字典序排序, 拼接成字符串s;
  7. 取出客户端访问密钥对应的secretkey, 对s计算HMACSHA256的值, 并编码为HEX, 得到 x-auth-signature;

Documentation

Overview

Package ginaksk 基于ak, sk实现的服务认证中间件

Example (Aksk)
package main

import (
	"crypto/md5"
	"encoding/base64"
	"errors"
	"fmt"
	"net/http"

	"github.com/antlinker/ginaksk"
	"github.com/gin-gonic/gin"
)

type store map[string]string

var keyStore = store{"ak": "sk"}

// GetKeyFunc 返回aksk.KeyFunc
func GetKeyFunc() ginaksk.KeyFunc {
	return func(ak string) string {
		return keyStore[ak]
	}
}

type logger struct{}

var testLogger = &logger{}

func (l *logger) Printf(format string, args ...interface{}) {
	fmt.Printf(format, args...)
}

func handlError(c *gin.Context, err error) {
	if err == nil {
		return
	}
	var aErr *ginaksk.Error
	if errors.As(err, &aErr) {
		c.AbortWithStatusJSON(http.StatusUnauthorized, map[string]interface{}{
			"err_code": 1,
			"err_msg":  err.Error(),
		})
		return
	}
	testLogger.Printf("aksk error: %s", err)
	c.AbortWithStatusJSON(http.StatusInternalServerError, map[string]interface{}{
		"err_code": -1,
		"err_msg":  err.Error(),
	})
}

type base64Encoder struct {
	enc *base64.Encoding
}

func (b64 *base64Encoder) EncodeToString(b []byte) string {
	return b64.enc.EncodeToString(b)
}

func (b64 *base64Encoder) DecodeString(s string) (b []byte, err error) {
	return b64.enc.DecodeString(s)
}

func main() {
	ginaksk.SetLogger(testLogger)                                  // 可选
	ginaksk.SetHash(md5.New)                                       // 可选
	ginaksk.SetEncoder(&base64Encoder{enc: base64.RawStdEncoding}) // 可选
	e := gin.New()
	// 验证请求签名, 并验证请求内容, 自定义错误处理
	e.Use(ginaksk.Validate(GetKeyFunc(), false, handlError))
	// ginaksk.SetHash(sha1.New) // [Bad!] 取消注释会触发panic
}
Output:

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrTimestampExpired 时间戳过期
	ErrTimestampExpired = newError("请求时间戳过期")
	// ErrTimestampInvalid 时间戳无效
	ErrTimestampInvalid = newError("请求时间戳无效")

	// ErrTimestampEmpty 缺少时间戳
	ErrTimestampEmpty = newError("请求缺少时间戳")
	// ErrSignatueEmpty 请求签名为空
	ErrSignatueEmpty = newError("请求缺少签名")
	// ErrSignatureInvalid 请求签名无效
	ErrSignatureInvalid = newError("请求签名无效")
	// ErrBodyInvalid 请求内容无效
	ErrBodyInvalid = newError("请求内容无效")
	// ErrBodyHashInvalid 请求内容哈希值无效
	ErrBodyHashInvalid = newError("请求内容哈希值无效")
)
View Source
var (
	// ErrAccessKeyEmpty ak为空
	ErrAccessKeyEmpty = newError("accesskey为空")
	// ErrSecretKeyEmpty sk为空
	ErrSecretKeyEmpty = newError("accesskey无效")
)

Functions

func SetEncoder

func SetEncoder(enc Encoder)

SetEncoder 设置编码实现,使用Validate后再次调用会panic

func SetHash

func SetHash(h HashFunc)

SetHash 使用自定义Hash算法,使用Validate后再次调用会panic

func SetLogger

func SetLogger(l Logger)

SetLogger 设置自定义的日志输出,使用Validate后再次调用会panic

func Validate

func Validate(keyFn KeyFunc, skipBody bool, fn ErrorHandler) gin.HandlerFunc

Validate 返回一个验证请求的gin中间件, keyFn指定了查询SecretKey的函数,如果等于nil,将panic; 如果skipBody为true, 跳过检查body的hash值是否一致; fn不为nil时,使用自定义的错误处理函数

Types

type Encoder

type Encoder interface {
	// EncodeToString 编码成字符串
	EncodeToString(b []byte) string
	// DecodeString 将字符串解码成字节切片
	DecodeString(s string) ([]byte, error)
}

Encoder 编码方法接口

type Error

type Error struct {
	// 错误消息
	Message string `json:"message"`
}

Error aksk的错误定义

func (*Error) Error

func (e *Error) Error() string

type ErrorHandler

type ErrorHandler func(c *gin.Context, err error)

ErrorHandler 错误处理函数

type HashFunc

type HashFunc func() hash.Hash

HashFunc 返回一个hash.Hash接口

type KeyFunc

type KeyFunc func(accessKey string) (secretKey string)

KeyFunc 查询accesskey,返回secretKey的函数

type Logger

type Logger interface {
	Printf(format string, args ...interface{})
}

Logger 日志

type RequestFunc

type RequestFunc func(ctx context.Context, method, url string, body []byte) (*http.Request, error)

RequestFunc aksk的请求构造函数

func NewRequestFunc

func NewRequestFunc(ak, sk string) (RequestFunc, error)

NewRequestFunc 返回一个RequestFunc

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL