使用 Apple 登录:在服务器端验证令牌



嗨,我正在尝试验证客户端应用程序提供的苹果身份验证凭据,在服务器端,我从客户端获取这些字段:authorizationCodeidentityToken以及许多其他字段。

我尝试阅读很多博客,但没有一个完全提到这些字段。 使用这些字段到某些苹果 API 来验证和获取用户详细信息的最简单方法

我已经为 Google 做到了这一点,客户端将访问令牌传递给后端,并使用https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=YourToken我们可以验证令牌并获取用户详细信息。

请为苹果建议一些类似的方法。谢谢。 我正在使用 ROR,以防有帮助。

最后,我能够弄清楚如何验证从客户端收到的访问令牌。 Apple不提供任何用于验证访问令牌的API,我强烈推荐此博客 它非常简洁地解释了整个过程。 这是相同的拼音代码链接。

对于那些需要 React-Native 客户端代码的人,请参见下文:

import * as React from 'react';
import * as AppleAuthentication from 'expo-apple-authentication';
import { signInWithApple } from '../api';
const AppleAuthenticationButton = () => (
<AppleAuthentication.AppleAuthenticationButton
buttonType={AppleAuthentication.AppleAuthenticationButtonType.SIGN_IN}
buttonStyle={AppleAuthentication.AppleAuthenticationButtonStyle.WHITE}
cornerRadius={5}
style={{ width: 200, height: 44 }}
onPress={async () => {
try {
const credential = await AppleAuthentication.signInAsync({
requestedScopes: [
AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
AppleAuthentication.AppleAuthenticationScope.EMAIL,
],
});
console.log('signed in', credential);
await signInWithApple(credential);
// signed in
} catch (e) {
if (e.code === 'ERR_CANCELED') {
console.log('cancelled');
// handle that the user canceled the sign-in flow
} else {
console.log('apple authentication error', e);
// handle other errors
}
}
}}
/>
);
export default AppleAuthenticationButton;
export const signInWithApple = async (credentials) => {
const {
identityToken, user, email, authorizationCode, fullName,
} = credentials;
apiCall('users/sign_in', 'post', {
method: 'apple',
identityToken,
user,
email,
authorizationCode,
fullName,
});
};

另外,正如我在下面的评论中指出的那样,我发现苹果凭据提供了 2 个密钥,其中只有一个有效。我不知道为什么,但以下代码比之前响应中链接的代码效果更好。

def validate_apple_id
name = params[:name]
userIdentity = params[:user]
jwt = params[:identityToken]
begin
header_segment = JSON.parse(Base64.decode64(jwt.split(".").first))
alg = header_segment["alg"]
apple_response = Net::HTTP.get(URI.parse(APPLE_PEM_URL))
apple_certificate = JSON.parse(apple_response)
token_data = nil
apple_certificate["keys"].each do | key |
keyHash = ActiveSupport::HashWithIndifferentAccess.new(key)
jwk = JWT::JWK.import(keyHash)
token_data ||= JWT.decode(jwt, jwk.public_key, true, {algorithm: alg})[0] rescue nil
end
if token_data&.has_key?("sub") && token_data.has_key?("email") && userIdentity == token_data["sub"]
yield
else
# TODO: Render error to app
end
rescue StandardError => e
# TODO: Render error to app
end
end

最新更新