Initial commit: VPN panel on Go, PostgreSQL 17, Docker, Xray-core
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
package session
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
const cookieName = "vpn_panel_session"
|
||||
const maxAge = 7 * 24 * time.Hour
|
||||
|
||||
type Data struct {
|
||||
UserID uuid.UUID `json:"uid"`
|
||||
Email string `json:"email"`
|
||||
Role string `json:"role"`
|
||||
Exp int64 `json:"exp"`
|
||||
}
|
||||
|
||||
func CookieName() string { return cookieName }
|
||||
|
||||
func Sign(secret string, d Data) (string, error) {
|
||||
d.Exp = time.Now().Add(maxAge).Unix()
|
||||
payload, err := json.Marshal(d)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
b64 := base64.RawURLEncoding.EncodeToString(payload)
|
||||
sig := sign(secret, b64)
|
||||
return b64 + "." + sig, nil
|
||||
}
|
||||
|
||||
func Verify(secret, token string) (*Data, error) {
|
||||
parts := strings.Split(token, ".")
|
||||
if len(parts) != 2 {
|
||||
return nil, errors.New("invalid token")
|
||||
}
|
||||
if sign(secret, parts[0]) != parts[1] {
|
||||
return nil, errors.New("bad signature")
|
||||
}
|
||||
raw, err := base64.RawURLEncoding.DecodeString(parts[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var d Data
|
||||
if err := json.Unmarshal(raw, &d); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if time.Now().Unix() > d.Exp {
|
||||
return nil, errors.New("expired")
|
||||
}
|
||||
return &d, nil
|
||||
}
|
||||
|
||||
func sign(secret, payload string) string {
|
||||
m := hmac.New(sha256.New, []byte(secret))
|
||||
m.Write([]byte(payload))
|
||||
return base64.RawURLEncoding.EncodeToString(m.Sum(nil))
|
||||
}
|
||||
Reference in New Issue
Block a user