refactor(10.2-01): nest framework packages under modules
- Move remaining beach packages and embedded admin assets\n- Rewrite framework, example, build, and gate paths
This commit is contained in:
78
modules/bouncer/mint.go
Normal file
78
modules/bouncer/mint.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package bouncer
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
)
|
||||
|
||||
// prvHash is sha1("Golem15\User\Models\User"), the lock-subject PHP jwt-auth
|
||||
// stamps on every frontend user token. Backend tokens do not carry it.
|
||||
const prvHash = "a867434cbc213adfbe78a02bed7082a6bd99c883"
|
||||
|
||||
const (
|
||||
// AudienceUser is the frontend jwt-guard audience.
|
||||
AudienceUser = "user"
|
||||
// AudienceBackend is the admin jwt-guard audience.
|
||||
AudienceBackend = "backend"
|
||||
)
|
||||
|
||||
type registeredClaims struct {
|
||||
jwt.RegisteredClaims
|
||||
Prv string `json:"prv,omitempty"`
|
||||
}
|
||||
|
||||
// Mint signs a frontend-audience HS256 token. iss is the minting endpoint URL.
|
||||
// The returned jti is the token's own jti claim.
|
||||
func Mint(secret, sub, issuerURL string, ttl time.Duration) (string, string, error) {
|
||||
return MintAudience(secret, sub, issuerURL, ttl, AudienceUser)
|
||||
}
|
||||
|
||||
// MintAudience signs an HS256 token for audience. Frontend tokens keep the PHP
|
||||
// prv lock-subject; backend tokens omit it.
|
||||
func MintAudience(secret, sub, issuerURL string, ttl time.Duration, audience string) (string, string, error) {
|
||||
if strings.TrimSpace(secret) == "" {
|
||||
return "", "", fmt.Errorf("bouncer: jwt secret is empty")
|
||||
}
|
||||
if strings.TrimSpace(audience) == "" {
|
||||
return "", "", fmt.Errorf("bouncer: jwt audience is empty")
|
||||
}
|
||||
jti, err := newJTI()
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
now := time.Now()
|
||||
prv := ""
|
||||
if audience == AudienceUser {
|
||||
prv = prvHash
|
||||
}
|
||||
claims := registeredClaims{
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
Issuer: issuerURL,
|
||||
Subject: sub,
|
||||
Audience: jwt.ClaimStrings{audience},
|
||||
ExpiresAt: jwt.NewNumericDate(now.Add(ttl)),
|
||||
NotBefore: jwt.NewNumericDate(now),
|
||||
IssuedAt: jwt.NewNumericDate(now),
|
||||
ID: jti,
|
||||
},
|
||||
Prv: prv,
|
||||
}
|
||||
signed, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString([]byte(secret))
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
return signed, jti, nil
|
||||
}
|
||||
|
||||
func newJTI() (string, error) {
|
||||
buf := make([]byte, 16)
|
||||
if _, err := rand.Read(buf); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return hex.EncodeToString(buf), nil
|
||||
}
|
||||
Reference in New Issue
Block a user