针对 Google 帐户关联的操作
Actions on Google account linking
根据 here 描述的文档,我使用隐式授权设置了帐户链接,发现它在使用浏览器/操作控制台以及 Google 家庭应用进行测试时效果很好Android。不幸的是,在 iphone 版本的应用程序中,用户身份验证大部分时间都挂起。 google 支持操作的反馈是,问题是 google 登录流程是在单独的浏览器选项卡 (window) 中实现的。在iphone你无法在SfariViewController中打开2windows,因此他们正在重写首页地址并且无法完成签到流程。这是已知问题,他们不打算更改此问题。解决方案是在一个浏览器中实现所有登录流程 window。我不清楚如何执行此操作,并且正在寻找某人共享您设置的授权 URL 背后的代码,该代码在 iphone 上始终有效。以下是我正在使用的核心:
.html 片段:
<!DOCTYPE html>
<html>
<head>
<title>Authorization Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="google-signin-client_id" content="948762963734-2kbegoe3i9ieqc6vjmabh0rqqkmxxxxx.apps.googleusercontent.com">
<!-- <meta name="google-signin-ux_mode" content="redirect"> INCLUDING THIS META TAG BREAKS THE AUTH FLOW -->
<script src="js/googleAuth.js"></script>
<script src="https://apis.google.com/js/platform.js" async defer></script>
<link rel="stylesheet" href="css/googleAuth.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<header class="bgimg-1 w3-display-container w3-grayscale-min" id="loginScreen">
<div class="w3-display-topleft w3-padding-xxlarge w3-text-yellow" style="top:5px">
<span class="w3-text-white">Google Sign In</span><br>
<span class="w3-large">Sign in with your Google account</span><br><br>
<div class="g-signin2" data-onsuccess="onSignIn"></div><br><br>
</div>
</header>
</body>
</html>
.js 代码片段:
function onSignIn(googleUser) {
var profile = googleUser.getBasicProfile();
var id = profile.getId()
var name = profile.getName()
var email = profile.getEmail()
var token = googleUser.getAuthResponse().id_token;
var client_id = getQueryVariable('client_id')
// vital-code-16xxx1 is the project ID of the google app
var redirect_uri = 'https://oauth-redirect.googleusercontent.com/r/vital-code-16xxx1'
var state = getQueryVariable('state')
var response_type = getQueryVariable('response_type')
// store the user's name, ID and access token and then sign out
storeOwnerID (email, name, id, token, function() {
// sign out
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
console.log('signed out')
});
// if this page was loaded by Actions On Google, redirect to complete authorization flow
typeof redirect_uri != 'undefined' ? window.location = redirectURL : void 0
})
}
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split('&');
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split('=');
if (decodeURIComponent(pair[0]) == variable) {
return decodeURIComponent(pair[1]);
}
}
console.log('Query variable %s not found', variable);
}
@dana 您是否尝试过添加元标记?
<meta name="google-signin-ux_mode" content="redirect">
在 Google 支持和工程的帮助下,现在已解决此问题:
- 如上所述,我必须包含此元标记:
<meta name="google-signin-ux_mode" content="redirect">
- 我需要在我的项目的授权重定向 URI 中包含 https://my-auth-endpoint.com/。仅在授权的 javascript 来源中拥有它是不够的。另一个关键是包括尾部斜线,我最初没有,没有它就无法工作。
下面是简单的代码基础,您可以使用它来获取授权端点的工作版本,以便对 google 帐户链接进行操作:
.html:
<!DOCTYPE html>
<html>
<head>
<title>Authorization Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="google-signin-client_id" content="948762963734-2kbegoe3i9ieqc6vjmabh0rqqkmxxxxx.apps.googleusercontent.com">
<meta name="google-signin-ux_mode" content="redirect">
<script src="js/googleAuth.js"></script>
<script src="https://apis.google.com/js/platform.js" async defer></script>
<link rel="stylesheet" href="css/googleAuth.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script>
sessionStorage['jsonData'] == null ? storeQueryVariables() : void 0
</script>
</head>
<body>
<header class="bgimg-1 w3-display-container w3-grayscale-min" id="loginScreen">
<div class="w3-display-topleft w3-padding-xxlarge w3-text-yellow" style="top:5px">
<span class="w3-text-white">Google Sign In</span><br>
<span class="w3-large">Sign in with your Google account</span><br><br>
<div class="g-signin2" data-onsuccess="onSignIn"></div><br><br>
</div>
</header>
</body>
</html>
.js:
// Retrieve user data, store to DynamoDB and complete the redirect process to finish account linking
function onSignIn(googleUser) {
let profile = googleUser.getBasicProfile(),
id = profile.getId(),
name = profile.getName(),
email = profile.getEmail(),
token = googleUser.getAuthResponse().id_token,
redirect_uri = 'https://oauth-redirect.googleusercontent.com/r/vital-code-16xxxx',
jsonData = JSON.parse(sessionStorage['jsonData']),
redirectURL = redirect_uri + '#access_token=' + token + '&token_type=bearer&state=' + jsonData.state
// store the user's name, ID and access token
storeUserData(email, name, id, token, function() {
// sign out of google for this app
let auth2 = gapi.auth2.getAuthInstance();
auth2.signOut()
// if this page was loaded by Actions On Google, redirect to complete authorization flow
typeof redirect_uri != 'undefined' ? window.location = redirectURL : void 0
})
}
// Store the user data to db
function storeUserData (email, name, id, token, callback) {
// removed for simplicity
}
// Store URI query variable 'state' to browser cache
function storeQueryVariables() {
let qvar = {
'state': getQueryVariable('state')
}
storeLocally(qvar)
}
// Get any variable from incoming URI
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split('&');
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split('=');
if (decodeURIComponent(pair[0]) == variable) {
return decodeURIComponent(pair[1]);
}
}
console.log('Query variable %s not found', variable);
}
// Store JSON object input to local browser cache
function storeLocally (jsonData) {
if (typeof(Storage) !== 'undefined') {
sessionStorage['jsonData'] = JSON.stringify(jsonData)
} else {
console.log('Problem: local web storage not available')
}
}
根据 here 描述的文档,我使用隐式授权设置了帐户链接,发现它在使用浏览器/操作控制台以及 Google 家庭应用进行测试时效果很好Android。不幸的是,在 iphone 版本的应用程序中,用户身份验证大部分时间都挂起。 google 支持操作的反馈是,问题是 google 登录流程是在单独的浏览器选项卡 (window) 中实现的。在iphone你无法在SfariViewController中打开2windows,因此他们正在重写首页地址并且无法完成签到流程。这是已知问题,他们不打算更改此问题。解决方案是在一个浏览器中实现所有登录流程 window。我不清楚如何执行此操作,并且正在寻找某人共享您设置的授权 URL 背后的代码,该代码在 iphone 上始终有效。以下是我正在使用的核心:
.html 片段:
<!DOCTYPE html>
<html>
<head>
<title>Authorization Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="google-signin-client_id" content="948762963734-2kbegoe3i9ieqc6vjmabh0rqqkmxxxxx.apps.googleusercontent.com">
<!-- <meta name="google-signin-ux_mode" content="redirect"> INCLUDING THIS META TAG BREAKS THE AUTH FLOW -->
<script src="js/googleAuth.js"></script>
<script src="https://apis.google.com/js/platform.js" async defer></script>
<link rel="stylesheet" href="css/googleAuth.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<header class="bgimg-1 w3-display-container w3-grayscale-min" id="loginScreen">
<div class="w3-display-topleft w3-padding-xxlarge w3-text-yellow" style="top:5px">
<span class="w3-text-white">Google Sign In</span><br>
<span class="w3-large">Sign in with your Google account</span><br><br>
<div class="g-signin2" data-onsuccess="onSignIn"></div><br><br>
</div>
</header>
</body>
</html>
.js 代码片段:
function onSignIn(googleUser) {
var profile = googleUser.getBasicProfile();
var id = profile.getId()
var name = profile.getName()
var email = profile.getEmail()
var token = googleUser.getAuthResponse().id_token;
var client_id = getQueryVariable('client_id')
// vital-code-16xxx1 is the project ID of the google app
var redirect_uri = 'https://oauth-redirect.googleusercontent.com/r/vital-code-16xxx1'
var state = getQueryVariable('state')
var response_type = getQueryVariable('response_type')
// store the user's name, ID and access token and then sign out
storeOwnerID (email, name, id, token, function() {
// sign out
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
console.log('signed out')
});
// if this page was loaded by Actions On Google, redirect to complete authorization flow
typeof redirect_uri != 'undefined' ? window.location = redirectURL : void 0
})
}
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split('&');
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split('=');
if (decodeURIComponent(pair[0]) == variable) {
return decodeURIComponent(pair[1]);
}
}
console.log('Query variable %s not found', variable);
}
@dana 您是否尝试过添加元标记?
<meta name="google-signin-ux_mode" content="redirect">
在 Google 支持和工程的帮助下,现在已解决此问题:
- 如上所述,我必须包含此元标记:
<meta name="google-signin-ux_mode" content="redirect">
- 我需要在我的项目的授权重定向 URI 中包含 https://my-auth-endpoint.com/。仅在授权的 javascript 来源中拥有它是不够的。另一个关键是包括尾部斜线,我最初没有,没有它就无法工作。
下面是简单的代码基础,您可以使用它来获取授权端点的工作版本,以便对 google 帐户链接进行操作:
.html:
<!DOCTYPE html>
<html>
<head>
<title>Authorization Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="google-signin-client_id" content="948762963734-2kbegoe3i9ieqc6vjmabh0rqqkmxxxxx.apps.googleusercontent.com">
<meta name="google-signin-ux_mode" content="redirect">
<script src="js/googleAuth.js"></script>
<script src="https://apis.google.com/js/platform.js" async defer></script>
<link rel="stylesheet" href="css/googleAuth.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script>
sessionStorage['jsonData'] == null ? storeQueryVariables() : void 0
</script>
</head>
<body>
<header class="bgimg-1 w3-display-container w3-grayscale-min" id="loginScreen">
<div class="w3-display-topleft w3-padding-xxlarge w3-text-yellow" style="top:5px">
<span class="w3-text-white">Google Sign In</span><br>
<span class="w3-large">Sign in with your Google account</span><br><br>
<div class="g-signin2" data-onsuccess="onSignIn"></div><br><br>
</div>
</header>
</body>
</html>
.js:
// Retrieve user data, store to DynamoDB and complete the redirect process to finish account linking
function onSignIn(googleUser) {
let profile = googleUser.getBasicProfile(),
id = profile.getId(),
name = profile.getName(),
email = profile.getEmail(),
token = googleUser.getAuthResponse().id_token,
redirect_uri = 'https://oauth-redirect.googleusercontent.com/r/vital-code-16xxxx',
jsonData = JSON.parse(sessionStorage['jsonData']),
redirectURL = redirect_uri + '#access_token=' + token + '&token_type=bearer&state=' + jsonData.state
// store the user's name, ID and access token
storeUserData(email, name, id, token, function() {
// sign out of google for this app
let auth2 = gapi.auth2.getAuthInstance();
auth2.signOut()
// if this page was loaded by Actions On Google, redirect to complete authorization flow
typeof redirect_uri != 'undefined' ? window.location = redirectURL : void 0
})
}
// Store the user data to db
function storeUserData (email, name, id, token, callback) {
// removed for simplicity
}
// Store URI query variable 'state' to browser cache
function storeQueryVariables() {
let qvar = {
'state': getQueryVariable('state')
}
storeLocally(qvar)
}
// Get any variable from incoming URI
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split('&');
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split('=');
if (decodeURIComponent(pair[0]) == variable) {
return decodeURIComponent(pair[1]);
}
}
console.log('Query variable %s not found', variable);
}
// Store JSON object input to local browser cache
function storeLocally (jsonData) {
if (typeof(Storage) !== 'undefined') {
sessionStorage['jsonData'] = JSON.stringify(jsonData)
} else {
console.log('Problem: local web storage not available')
}
}