github.com/zhiqiangxu/util@v0.0.0-20230112053021-0a7aee056cd5/crypto/claim/verifier.go (about)

     1  package claim
     2  
     3  import (
     4  	"crypto/rsa"
     5  	"encoding/json"
     6  	"fmt"
     7  	"time"
     8  
     9  	"github.com/dgrijalva/jwt-go"
    10  )
    11  
    12  // Verifier for claims
    13  type Verifier struct {
    14  	method    jwt.SigningMethod
    15  	verifyKey *rsa.PublicKey
    16  }
    17  
    18  // NewVerifier is ctor for Verifier
    19  func NewVerifier(verifyKey *rsa.PublicKey) (v *Verifier, err error) {
    20  	signingAlgorithm := "RS256"
    21  	method := jwt.GetSigningMethod(signingAlgorithm)
    22  	if method == nil {
    23  		err = fmt.Errorf("invalid signingAlgorithm:%s", method)
    24  		return
    25  	}
    26  
    27  	v = &Verifier{method: method, verifyKey: verifyKey}
    28  	return
    29  }
    30  
    31  // Verify claims
    32  func (v *Verifier) Verify(tokenString string) (ok bool, values map[string]interface{}) {
    33  	ok, values = verify(tokenString, v.method, v.verifyKey)
    34  	return
    35  }
    36  
    37  // GetInt64 for retrieve claim value as int64
    38  func GetInt64(value interface{}) (int64Value int64) {
    39  	switch exp := value.(type) {
    40  	case float64:
    41  		int64Value = int64(exp)
    42  	case json.Number:
    43  		int64Value, _ = exp.Int64()
    44  	}
    45  	return
    46  }
    47  
    48  func verify(tokenString string, method jwt.SigningMethod, verifyKey interface{}) (ok bool, values map[string]interface{}) {
    49  	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (key interface{}, err error) {
    50  		if method != token.Method {
    51  			err = fmt.Errorf("invalid signingAlgorithm:%s", token.Method.Alg())
    52  			return
    53  		}
    54  		key = verifyKey
    55  		return
    56  	})
    57  	if err != nil || !token.Valid {
    58  		return
    59  	}
    60  
    61  	claims, ok := token.Claims.(jwt.MapClaims)
    62  	if !ok {
    63  		return
    64  	}
    65  
    66  	expireAt, exists := claims[ExpireATKey]
    67  	if !exists {
    68  		ok = false
    69  		return
    70  	}
    71  
    72  	ok = verifyExp(GetInt64(expireAt))
    73  	if !ok {
    74  		return
    75  	}
    76  
    77  	values = (map[string]interface{})(claims)
    78  	delete(values, ExpireATKey)
    79  	delete(values, CreatedKey)
    80  	return
    81  }
    82  
    83  func verifyExp(exp int64) (ok bool) {
    84  	nowSecond := time.Now().Unix()
    85  	ok = exp > nowSecond
    86  	return
    87  }