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
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) |
|
}
|
|
|