You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

96 lines
2.2 KiB

package server
import (
"encoding/base64"
"encoding/json"
"github.com/gin-gonic/gin"
"net/http"
"texas-poker-bk/tool/security"
)
var (
SubjectKey = "auth:subject"
sc = &scEtc{} // 加密配置
)
// Subject 认证对象
type Subject struct {
Id int64 `json:"id,omitempty"` // 用户id
Name string `json:"name,omitempty"` // 用户名
Time int64 `json:"time,omitempty"` // 生成时间戳
}
type scEtc struct {
securityKey string
keyBytes []byte
}
func init() {
sc.securityKey = "9Nz3Y6DES3msAFndz4QsJAECUIFkf+KKaRa+jRnNALk="
keyBytes, err := base64.URLEncoding.DecodeString(sc.securityKey)
if err != nil {
panic(err)
}
sc.keyBytes = keyBytes
}
// SubjectAuthFilter 认证过滤器
func SubjectAuthFilter(ctx *gin.Context) {
auth := ctx.GetHeader("Authorization")
if auth == "" {
// TODO config ignore urls
//if isIgnoreUrl(ctx.Request.URL.Path) {
// return
//}
ctx.JSON(http.StatusUnauthorized, gin.H{"msg": "请登录后进行操作"})
ctx.Abort()
return
}
defer func() {
// 捕获aes解析错误
if r := recover(); r != nil {
ctx.JSON(http.StatusUnauthorized, gin.H{"msg": "认证失败,请重新登录"})
ctx.Abort()
}
}()
// TODO 这里返回 error,不然后捕获后续执行 handler 的 panic
subject := DecodeSubject(auth)
ctx.Set(SubjectKey, subject)
}
// EncodeSubject 对subject对象aesCBC加密并返回base64Std编码的 token
// subject 客户端对象
func EncodeSubject(subject *Subject) string {
bytes, err := json.Marshal(subject)
if err != nil {
panic(err)
}
encode := security.EncryptAesCBC(bytes, sc.keyBytes)
return base64.URLEncoding.EncodeToString(encode)
}
// DecodeSubject 解码并解密token返回subject对象
// auth base64Std 编码的 token
func DecodeSubject(auth string) *Subject {
bytes, err := base64.URLEncoding.DecodeString(auth)
if err != nil {
panic(err)
}
decode := security.DecryptAesCBC(bytes, sc.keyBytes)
subject := &Subject{}
err = json.Unmarshal(decode, subject)
if err != nil {
panic(err)
}
return subject
}
// GetSubject 从请求上下文中获取客户端对象, 请求经过了认证过滤器
func GetSubject(ctx *gin.Context) *Subject {
subject, exists := ctx.Get(SubjectKey)
if !exists {
return nil
}
return subject.(*Subject)
}