package thirdparty
import (
"crypto/rsa"
"fmt"
"github.com/dgrijalva/jwt-go"
"github.com/lestrrat-go/jwx/jwk"
"github.com/pkg/errors"
"github.com/wonderivan/logger"
"math/big"
"net/http"
)
func bigFromByte(s []uint8) *big.Int {
ret := new(big.Int)
ret.SetBytes(s)
return ret
}
// 解析token
func AppleParseToken(appleToken string) (string, error) {
set, err := jwk.FetchHTTP("https://appleid.apple.com/auth/keys",
jwk.WithHTTPClient(http.DefaultClient))
if err != nil {
return "", err
}
var isSuccess bool
var token *jwt.Token //要對每一個公鑰都去進行解析,有一個成功了就行,全失敗才算失敗
for _, key := range set.Keys {
fmt.Println(key)
NIface, _ := key.Get("n")
NStr := NIface.([]uint8)
EIface, _ := key.Get("e")
EStr := EIface.([]uint8)
pubKey := &rsa.PublicKey{N: bigFromByte(NStr), E: int(bigFromByte(EStr).Int64())}
token, err = jwt.Parse(appleToken, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
logger.Error("Unexpected signing method: %v", token.Header["alg"])
}
return pubKey, nil
})
if err != nil {
logger.Error("Token Parse error:", err)
continue
}
if !token.Valid {
logger.Error("Token is invalid")
continue
}
isSuccess = true
break
}
if isSuccess == false {
return "", errors.New("Token is invalid")
}
claims := token.Claims.(jwt.MapClaims)
sub, ok := claims["sub"].(string)
if !ok || sub == "" {
return "", errors.New("Token abnormal")
}
logger.Info("Token verification success")
return sub, nil
}
本文摘自 :https://blog.51cto.com/u