概述
这里记录了,接入AppleID登录,服务端的实现。
针对后端验证苹果提供了两种验证方式:
- 一种是 基于JWT的算法验证
- 一种是 基于授权码的验证
identityToken是一个经过签名的JSON Web Token的方式实现,更多见Sign in with Apple REST API。
另一种方式是校验授权码,其主要分为两步:1. 用户授权后获取code;2. 通过code换取token。
服务端验证identityToken时,App客户端需要将苹果接口返回的identityToken, userID这两个参数传递给服务器,用于验证本次登录的有效性。
服务端,获取到Apple公钥,来验证identityToken的有效性。
公钥获取接口:https://appleid.apple.com/auth/keys , 文档见Fetch Apple’s Public Key for Verifying Token Signature。
实现
代码在GitHub。
实现1,主要使用github.com/dgrijalva/jwt-go 和 github.com/lestrrat-go/jwx/jwk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
func VerfiyToken(token string) error {
_, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) {
set, err := jwk.Fetch(context.Background(), "https://appleid.apple.com/auth/keys")
if err != nil {
return nil, err
}
kid := t.Header["kid"]
if key, ok := set.LookupKeyID(fmt.Sprint(kid)); ok {
if _, ok := t.Method.(*jwt.SigningMethodRSA); !ok {
return nil, fmt.Errorf("unexpected signing method: %s", t.Header["alg"])
}
var rawKey interface{}
if err = key.Raw(&rawKey); err != nil {
return nil, err
}
return rawKey, nil
}
return nil, nil
})
return err
}
|
实现2 github.com/lestrrat-go/jwx/jwk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
func VerifyToken2(payload string) error {
set, err := jwk.Fetch(context.Background(), "https://appleid.apple.com/auth/keys")
if err != nil {
return err
}
token, err := ljwt.Parse([]byte(payload), ljwt.WithKeySet(set), ljwt.UseDefaultKey(true))
if err != nil {
return err
}
fmt.Println(token)
return nil
}
|