我们有一个应用程序,它依赖于Google根据我们的Google apps帐户对其用户进行身份验证,然后进行一些服务器端验证和组查找。
最近google更改了保存我们需要进行身份验证的access_token变量的对象的名称。在文档(https://developers.google.com/identity/sign-in/web/reference#googleusergetbasicprofile)中,它说access_token可以从getAuthResponse()方法中获得,但是当我使用它时,它返回为未定义。在console.log()之后检查对象,会发现除了access_token之外提到的所有其他字段。我担心Google将来会再次更改对象,让我们失去应用程序。代码如下:
<head>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css">
<script src="https://apis.google.com/js/platform.js" async defer></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<meta name="google-signin-client_id" content="XXX.apps.googleusercontent.com">
<script>
//This happens after the user has authenticated with Google and has been passed
//back to the page
function onSignIn(googleUser) {
//Check to see whether the user is trying to sign out.
if (window.location.href.indexOf("signOut=1") !== -1) {
//Sign them out of the application.
signOut();
//redirect them to the same page, without the signOut query string so they can log back in if want
window.location.href='googlesigninform.html'
return false;
}
//Grab the token, access token and email.
var _id = googleUser.getAuthResponse().id_token; //This works
var _accessToken = googleUser.Ka.access_token; //This works but changed from googleUser.B.access_token
var profile = googleUser.getBasicProfile(); //Works
console.log(googleUser.access_token); //Undefined
console.log(googleUser.getAuthResponse().access_token);//Undefined
//Make a post request to the API
makePostRequest(_id, _accessToken, profile.getEmail());
}
访问access_token变量的正确方法是什么?
如果您需要使用访问令牌,您正在使用错误类型的谷歌登录流程。你应该关注这个页面:https://developers.google.com/identity/sign-in/web/server-side-flow
你所实现的是google Sign-In识别用户(https://developers.google.com/identity/sign-in/web/)
它只为每个用户提供唯一的id,因为它意味着为您自己的服务验证用户,而不是为以后的其他Google服务提供访问令牌。
我认为您的问题在于您的应用程序缺乏必要的google-signin-scope
。
为了回答你的问题,我使用Google Developer Console
从地面创建了一个应用程序。应用程序非常简单,就像这个tutorial
。
整个应用程序由一个简单的HTML组成,它加载了google API,并有一个名为onSignIn的回调(就像你的)。
下面是应用程序的完整代码:
<html lang="en">
<head>
<meta name="google-signin-scope" content="profile email">
<meta name="google-signin-client_id" content="PLACE_YOUR_ID_HERE.apps.googleusercontent.com">
<script src="https://apis.google.com/js/platform.js" async defer></script>
</head>
<body>
<div class="g-signin2" data-onsuccess="onSignIn" data-theme="dark"></div>
<script>
function onSignIn(googleUser) {
var response = googleUser.getAuthResponse(),
idToken = response['id_token'],
accessToken = response['access_token'];
console.dir('id token: ' + idToken);
console.dir('access token: ' + accessToken);
}
</script>
</body>
</html>
正如您所看到的,我的应用程序和您的应用程序之间的区别在于您的应用程序缺少第一个META
属性。
我有一个破解工作,从变量中获取access_token。
function findAccessToken(googleUser) {
var returnValue;
Object.getOwnPropertyNames(googleUser).forEach(function (val, idx, array) {
console.log(val + ' -> ' + googleUser[val]);
Object.getOwnPropertyNames(googleUser[val]).forEach(function (vals, idxs, arrays) {
if (vals === "access_token") {
console.log("true");
returnValue = googleUser[val][vals];
}
});
});
return returnValue;
}
这肯定不是最优雅的解决方案。如果有人能指出正确的方向,那就太好了。
下面是使用google登录的代码。
<html lang="en">
<head>
<meta name="google-signin-scope" content="profile email">
<meta name="google-signin-client_id" content="YOUR_CLIENT_ID.apps.googleusercontent.com">
<script src="https://apis.google.com/js/platform.js" async defer></script>
</head>
<body>
<div class="g-signin2" data-onsuccess="onSignIn" data-theme="dark"></div>
<script>
function onSignIn(googleUser) {
// Useful data for your client-side scripts:
var profile = googleUser.getBasicProfile();
console.log("ID: " + profile.getId()); // Don't send this directly to your server!
console.log("Name: " + profile.getName());
console.log("Image URL: " + profile.getImageUrl());
console.log("Email: " + profile.getEmail());
// The ID token you need to pass to your backend:
var id_token = googleUser.getAuthResponse().id_token;
console.log("ID Token: " + id_token);
};
</script>
</body>
</html>
试试这个var _access_token = GoogleUser.getAuthResponse().access_token