使用不重定向的 Capacitor 插件在 Web 上使用 Apple 登录
Sign in with apple on the web with Capacitor plugin not redirecting
我正在尝试在我的 Ionic 应用程序中实现使用 Apple 登录功能。为此,我正在使用插件:https://github.com/capacitor-community/apple-sign-in
在设备上使用时一切正常,但我无法将其用作网络应用程序。
这就是我开始流程的方式:
SignInWithApple.authorize({
clientId: environment.appId+'.webapp',
redirectURI: 'https://api.xxxx.hu/signInWithAppleCallback',
scopes: 'email name',
state: '12345',
//nonce: 'nonce',
}).then(appleUser => {
this.sendOauthConnectRequest(OauthProvider.apple, appleUser.response.identityToken).subscribe();
}).catch(() => {
this.oauthLoading[oauthProvider] = false;
return;
});
clientId 是我在 apple 注册的,重定向 url 也可以。
当我开始这个调用时,会弹出一个新的 window,我可以在其中使用我的 apple ID 登录,但完成后,它不会将我重定向到指定的 URL。事实上,什么也没有发生。控制台中也没有错误。我可以看到对“https://appleid.apple.com/appleauth/auth/oauth/authorize”的请求成功,并且在响应中我可以看到所有正确的身份验证数据,只是重定向没有发生。如果我在那之后关闭登录 window,错误处理程序的回调被正确调用,从而通知我登录不成功(这是预期的,因为用户关闭了 window).
那么关于为什么重定向没有发生的任何想法?
非常感谢!
仅供参考,这是我使用的解决方案。
基本上,它的第一部分只是将网络平台与真实设备分开。
if (Capacitor.getPlatform() === 'web') {
this.appleSignInAbortController = new AbortController();
this.appleSignInWindow = window.open(
'https://appleid.apple.com/auth/authorize?' +
'client_id=com.company.exampleApp&'+
'redirect_uri='+environment.appUrl+'&' +
'response_type=code id_token&' +
'scope=name email&' +
'response_mode=web_message',
'_blank'
);
window.addEventListener(
'message',
(e) => {this.appleTokenReceived(e);},
{signal: this.appleSignInAbortController.signal}
);
return;
}
//Continue with regular sign in on real devices, just like in the original post
appleTokenReceived 是一个调用 Apple 响应的函数。请注意,响应也将发布到指定的 redirect_uri,但这将在后台发生,server-to-server,因此您不能真正使用它来重定向您的客户端(除非您打开一个websocket 到你的服务器,但这对于这个任务来说似乎有点矫枉过正)。所以另一半代码:
async appleTokenReceived(event) {
this.appleSignInAbortController.abort();
this.appleSignInWindow.close();
if (!(event instanceof MessageEvent)) {
return;
}
const data = JSON.parse(event.data);
if (typeof data !== 'object' || data === null) {
return;
}
if (data.data.hasOwnProperty('error')) {
return;
}
let postData: any = {
token: data.data.authorization.id_token,
device_id: 'device UUID',
};
if (
data.data.hasOwnProperty('user') &&
data.data.user.hasOwnProperty('name') &&
data.data.user.name.hasOwnProperty('firstName') &&
data.data.user.name.hasOwnProperty('lastName')
) {
//this is only filled after the first login of the user
postData.name = data.data.user.name.lastName + ' ' + data.data.user.name.firstName;
}
this.http.post(environment.apiUrl + '/api/auth/loginWithApple', postData).subscribe(//Do whatever you need with the data);
}
我正在尝试在我的 Ionic 应用程序中实现使用 Apple 登录功能。为此,我正在使用插件:https://github.com/capacitor-community/apple-sign-in
在设备上使用时一切正常,但我无法将其用作网络应用程序。 这就是我开始流程的方式:
SignInWithApple.authorize({
clientId: environment.appId+'.webapp',
redirectURI: 'https://api.xxxx.hu/signInWithAppleCallback',
scopes: 'email name',
state: '12345',
//nonce: 'nonce',
}).then(appleUser => {
this.sendOauthConnectRequest(OauthProvider.apple, appleUser.response.identityToken).subscribe();
}).catch(() => {
this.oauthLoading[oauthProvider] = false;
return;
});
clientId 是我在 apple 注册的,重定向 url 也可以。 当我开始这个调用时,会弹出一个新的 window,我可以在其中使用我的 apple ID 登录,但完成后,它不会将我重定向到指定的 URL。事实上,什么也没有发生。控制台中也没有错误。我可以看到对“https://appleid.apple.com/appleauth/auth/oauth/authorize”的请求成功,并且在响应中我可以看到所有正确的身份验证数据,只是重定向没有发生。如果我在那之后关闭登录 window,错误处理程序的回调被正确调用,从而通知我登录不成功(这是预期的,因为用户关闭了 window). 那么关于为什么重定向没有发生的任何想法? 非常感谢!
仅供参考,这是我使用的解决方案。 基本上,它的第一部分只是将网络平台与真实设备分开。
if (Capacitor.getPlatform() === 'web') {
this.appleSignInAbortController = new AbortController();
this.appleSignInWindow = window.open(
'https://appleid.apple.com/auth/authorize?' +
'client_id=com.company.exampleApp&'+
'redirect_uri='+environment.appUrl+'&' +
'response_type=code id_token&' +
'scope=name email&' +
'response_mode=web_message',
'_blank'
);
window.addEventListener(
'message',
(e) => {this.appleTokenReceived(e);},
{signal: this.appleSignInAbortController.signal}
);
return;
}
//Continue with regular sign in on real devices, just like in the original post
appleTokenReceived 是一个调用 Apple 响应的函数。请注意,响应也将发布到指定的 redirect_uri,但这将在后台发生,server-to-server,因此您不能真正使用它来重定向您的客户端(除非您打开一个websocket 到你的服务器,但这对于这个任务来说似乎有点矫枉过正)。所以另一半代码:
async appleTokenReceived(event) {
this.appleSignInAbortController.abort();
this.appleSignInWindow.close();
if (!(event instanceof MessageEvent)) {
return;
}
const data = JSON.parse(event.data);
if (typeof data !== 'object' || data === null) {
return;
}
if (data.data.hasOwnProperty('error')) {
return;
}
let postData: any = {
token: data.data.authorization.id_token,
device_id: 'device UUID',
};
if (
data.data.hasOwnProperty('user') &&
data.data.user.hasOwnProperty('name') &&
data.data.user.name.hasOwnProperty('firstName') &&
data.data.user.name.hasOwnProperty('lastName')
) {
//this is only filled after the first login of the user
postData.name = data.data.user.name.lastName + ' ' + data.data.user.name.firstName;
}
this.http.post(environment.apiUrl + '/api/auth/loginWithApple', postData).subscribe(//Do whatever you need with the data);
}