我正在应用程序和Web上都应用Apple Signin。但是,如果我登录Web并进行验证,Apple服务器将始终返回错误invalid_grant
。
以下是我的服务的简单环境。
该应用是由ReactNative制作的,服务器是nodejs。
例如,证书值如下。
TeamID : 9BF12A
AppID : com.foo
ServiceID : com.foo.web (its bound primary key(?) is AppID com.foo)
KeyID : 12ABC4 (its bound primary key(?) is AppID com.foo)
...
在应用中登录后,它将authorizationCode
和identityToken
发送到服务器网址/auth/apple
。
在网络上登录时,它会打开Apple登录页面。并且,在完成登录过程后,Apple会将code
和id_token
返回到服务器URL /auth/apple
(引用here)。
因此,在我的服务器路由/auth/apple
中,我从应用程序和网络收到code(authorizationCode)
和id_token(identityToken)
。
为了验证id_token
,我制作了client_secret
并使用以下函数验证code
// isrn : if the values(code and id_token) are come from the app(react native)
const get_client_secret = isrn => {
// sign with RSA SHA256
const privateKey = get_private_key(); // pseudo
const token = jwt.sign({}, privateKey, {
algorithm: 'ES256',
expiresIn: '10h',
audience: 'https://appleid.apple.com',
issuer: 9BF12A, // TeamID
subject: isrn ? com.foo : com.foo.web, // if the code from react native app, use AppID, else use ServiceID
keyid: 12ABC4,
});
return token;
};
const verify = (code, isrn) => {
let b;
let e;
return new Promise(resolve => {
axios.post(
'https://appleid.apple.com/auth/token',
querystring.stringify({
grant_type: 'authorization_code',
code,
client_secret: get_client_secret(isrn),
client_id: isrn ? com.foo : com.foo.web,
redirect_uri: 'https://testurl.com/auth/apple',
}),
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
})
.then(r => {
b = r.data;
})
.catch(err => {
e = err.response ? err.response.data : { err };
})
.finally(() => {
resolve({ b, e });
});
}).catch(err => {
resolve({ b, e: err });
});
};
我就像在路由/auth/apple
中使用它
app.post('/auth/apple', (req, res, _) => {
const { body: { isrn, code, id_token } } = req;
verify(code, isrn).then(({ b, e }) => {
// if code came from the app, b has result values like access_token and e is undefined
// but if code came from the web, b is undefined and e has value 'invalid_grant'
log('******* verify : ', b, e);
// some process
});
});
当code
和id_token
来自网络时,错误将以invalid_grant
返回,但对于app,返回值可以。
如何像应用程序一样验证来自网络的code
?
或者,我不能?
答案 0 :(得分:0)
确保您使用的代码尚未过期。
授权响应中收到的授权码已发送至 您的应用。该代码仅供一次性使用,有效期为五分钟。
https://developer.apple.com/documentation/sign_in_with_apple/generate_and_validate_tokens