1.4.5.2
This commit is contained in:
58
EdgeAdmin/internal/csrf/token_manager.go
Normal file
58
EdgeAdmin/internal/csrf/token_manager.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package csrf
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var sharedTokenManager = NewTokenManager()
|
||||
|
||||
func init() {
|
||||
go func() {
|
||||
ticker := time.NewTicker(1 * time.Hour)
|
||||
for range ticker.C {
|
||||
sharedTokenManager.Clean()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
type TokenManager struct {
|
||||
tokenMap map[string]int64 // token => timestamp
|
||||
|
||||
locker sync.Mutex
|
||||
}
|
||||
|
||||
func NewTokenManager() *TokenManager {
|
||||
return &TokenManager{
|
||||
tokenMap: map[string]int64{},
|
||||
}
|
||||
}
|
||||
|
||||
func (this *TokenManager) Put(token string) {
|
||||
this.locker.Lock()
|
||||
this.tokenMap[token] = time.Now().Unix()
|
||||
this.locker.Unlock()
|
||||
}
|
||||
|
||||
func (this *TokenManager) Exists(token string) bool {
|
||||
this.locker.Lock()
|
||||
_, ok := this.tokenMap[token]
|
||||
this.locker.Unlock()
|
||||
return ok
|
||||
}
|
||||
|
||||
func (this *TokenManager) Delete(token string) {
|
||||
this.locker.Lock()
|
||||
delete(this.tokenMap, token)
|
||||
this.locker.Unlock()
|
||||
}
|
||||
|
||||
func (this *TokenManager) Clean() {
|
||||
this.locker.Lock()
|
||||
for token, timestamp := range this.tokenMap {
|
||||
if time.Now().Unix()-timestamp > 3600 { // 删除一个小时前的
|
||||
delete(this.tokenMap, token)
|
||||
}
|
||||
}
|
||||
this.locker.Unlock()
|
||||
}
|
||||
66
EdgeAdmin/internal/csrf/utils.go
Normal file
66
EdgeAdmin/internal/csrf/utils.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package csrf
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/configs"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Generate 生成Token
|
||||
func Generate() string {
|
||||
timestamp := strconv.FormatInt(time.Now().Unix(), 10)
|
||||
|
||||
h := sha256.New()
|
||||
h.Write([]byte(configs.Secret))
|
||||
h.Write([]byte(timestamp))
|
||||
s := h.Sum(nil)
|
||||
token := base64.StdEncoding.EncodeToString([]byte(timestamp + fmt.Sprintf("%x", s)))
|
||||
sharedTokenManager.Put(token)
|
||||
return token
|
||||
}
|
||||
|
||||
// Validate 校验Token
|
||||
func Validate(token string) (b bool) {
|
||||
if len(token) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if !sharedTokenManager.Exists(token) {
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
sharedTokenManager.Delete(token)
|
||||
}()
|
||||
|
||||
data, err := base64.StdEncoding.DecodeString(token)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
hashString := string(data)
|
||||
if len(hashString) < 10+32 {
|
||||
return
|
||||
}
|
||||
|
||||
timestampString := hashString[:10]
|
||||
hashString = hashString[10:]
|
||||
|
||||
h := sha256.New()
|
||||
h.Write([]byte(configs.Secret))
|
||||
h.Write([]byte(timestampString))
|
||||
hashData := h.Sum(nil)
|
||||
if hashString != fmt.Sprintf("%x", hashData) {
|
||||
return
|
||||
}
|
||||
|
||||
timestamp := types.Int64(timestampString)
|
||||
if timestamp < time.Now().Unix()-1800 { // 有效期半个小时
|
||||
return
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user