I'm trying to add Apple sign-in functionality to my Android App. I follow the pop-up approach. I'm failing to get it to work.
class AppleLoginWebViewActivity : BaseActivity(), AppleLoginContract.View {
private val TAG = AppleLoginWebViewActivity::class.java.simpleName
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_apple_login)
prepareWebView()
}
private fun prepareWebView() {
if (BuildConfig.DEBUG) {
WebView.setWebContentsDebuggingEnabled(true)
}
webView.addJavascriptInterface(
AppleLoginJavaScriptInterface(),
"AndroidInterface"
)
val webSettings: WebSettings = webView.settings
webSettings.javaScriptEnabled = true
webView.webViewClient = MyWebViewClient()
webView.webChromeClient = MyWebChromeClient()
webView.settings.loadWithOverviewMode = true
webView.settings.domStorageEnabled = true
webView.settings.useWideViewPort = true
}
private inner class MyWebViewClient : WebViewClient() {
override fun onPageFinished(
view: WebView,
url: String
) { //Calling a javascript function in html page
Logger.info(TAG, "page started: $url")
// view.loadUrl("javascript:alert(clickAppleSignInButton())")
view.loadUrl("javascript:AndroidInterface.showHTML" +
"('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>');");
}
override fun shouldOverrideUrlLoading(
view: WebView?,
request: WebResourceRequest?
): Boolean {
return false
}
}
private class MyWebChromeClient : WebChromeClient() {
override fun onJsAlert(
view: WebView,
url: String,
message: String,
result: JsResult
): Boolean {
result.confirm()
return true
}
}
override fun loadUrl(appleLoginLocalUrl: String) {
webView.loadUrl(appleLoginLocalUrl)
}
}
and here is the html file that I load
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Apple Sign in</title>
</head>
<body>
<script type="text/javascript" src="https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js"></script>
<div id="appleid-signin" data-color="black" data-border="true" data-type="sign in"></div>
<script type="text/javascript">
const options = {
clientId: 'MY_CLIENT_ID',
scope: 'email name',
redirectURI: 'MY_REDIRECT_URL',
state: '',
usePopup : true
};
AppleID.auth.init(options);
</script>
<script type="text/javascript">
function clickAppleSignInButton() {
document.getElementById("appleid-signin").click();
}
</script>
<script type="text/javascript">
//Listen for authorization success
document.addEventListener('AppleIDSignInOnSuccess', successFunction);
//Listen for authorization failures
document.addEventListener('AppleIDSignInOnFailure', failureFunction);
function successFunction(data) {
//handle successful response
console.log("success")
AndroidInterface.onLoginSuccess(data);
}
function failureFunction(error) {
//handle error
console.log("failure")
AndroidInterface.onLoginFailed(error);
}
</script>
</body>
</html>
SO, in the last step, when I inspect the web view, I can see the authentication data being posted (POST request) to another url inside the web view. But the event listener with AppleIDSignInOnSuccess
is never called. there is an error that says "Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('MY_REDIRECT_URL') does not match the recipient window's origin ('https://appleid.apple.com').", source: (0)
.
So, I have a couple of questions:
You can sign in to Apple Music on Android, or sign in to the Apple TV app on your smart TV or streaming device.
<script type="text/javascript">
const options = {
clientId: 'MY_CLIENT_ID',
scope: 'email name',
redirectURI: 'MY_REDIRECT_URL',
state: '',
usePopup : true
};
AppleID.auth.init(options);
AppleID.auth.signIn(); //<-- there :)
</script>
https://some.domain.tld/path/to/redirect
which supports POSTIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With