Go语言实现APPID登录
阅读原文时间:2023年07月08日阅读:1
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
}