- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试对 Google Developer's website 中描述的 Google+ 网络登录服务器端流程进行细微改动。 .
我有一个员工登录页面 (staff_login.php),它通过 Google+ (plusone.js) 使用 javascript。如果用户已经登录到 Google,则来自 Google 的授权代码将存储到 session 变量中。如果用户未登录,则会显示“员工登录”按钮。如果用户单击该按钮,则会进行 Google 授权,如果成功,则来自 Google 的授权代码将存储到 session 变量中。在这两种情况下,在存储 session 变量后,用户将被重定向到另一个网页 (google_login.php)。
大多数情况下,登录过程会按预期进行,但有时 google_login.php 会生成一条错误消息:Google_Auth_Exception,消息为“获取 OAuth2 访问 token 时出错,消息:‘invalid_grant’”。
我相当确定问题出在 signInCallback 函数中。如何使其防弹?
这是(缩减)代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="google-signin-clientid"
content="CLIENT-ID.apps.googleusercontent.com">
<meta name="google-signin-scope" content="email">
<meta name="google-signin-cookiepolicy" content="single_host_origin">
<meta name="google-signin-callback" content="signInCallback">
<title>Login</title>
</head>
<body>
<button id="xyzStaffSignIn">Staff Sign In</button>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"
type="text/javascript"></script>
<script type = "text/javascript" >
jQuery(document).ready(function ($) {
console.log('Google (plusone.js) will invoke signInCallback');
window.___gcfg = {
lang: 'en-GB',
parsetags: 'onload'
};
var po = document.createElement('script');
po.type = 'text/javascript';
po.async = true;
po.src = 'https://apis.google.com/js/client:plusone.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(po, s);
});
function signInCallback(authResult) {
if (authResult) {
if (authResult['error'] == undefined) {
if (authResult['code']) {
setSessionValue('GoogleAuthorisationCode',
authResult['code'], callGoogleLogin);
}
} else if (authResult['error']) {
// There was an error.
// Possible error codes:
// "access_denied" - User denied access to your app
// "immediate_failed" - Could not automatically log in the user
console.log('There was an error: ' + authResult['error']);
if (!authResult['status']['signed_in']) {
console.log('gapi.signin.render will invoke signInCallback');
gapi.signin.render('xyzStaffSignIn');
}
} else {
console.log('Empty authResult'); // Something went wrong
}
}
}
function setSessionValue(key, value, callback) {
$.post(
'session.php',
{
xyzAction: 'set',
xyzKey: key,
xyzValue: value
},
function (result) {
// Handle or verify the server response if necessary.
if (result['status'] == undefined) {
alert('xyz status problem. Please email our IT department!');
} else {
switch (result['status']) {
case 'Success':
callback();
break;
default:
alert('xyz unexpected status problem.
Please email our IT department!');
console.log(result['status']);
}
}
}
)
}
function callGoogleLogin() {
gapi.client.load('plus', 'v1', loadProfile);
}
/**
* Uses the JavaScript API to request the user's profile, which includes
* their basic information. When the plus.profile.emails.read scope is
* requested, the response will also include the user's primary email address
* and any other email addresses that the user made public.
*/
function loadProfile() {
var request = gapi.client.plus.people.get({'userId': 'me'});
request.execute(loadProfileCallback);
}
/**
* Callback for the asynchronous request to the people.get method. The profile
* and email are set to global variables. Triggers the user's basic profile
* to display when called.
*/
function loadProfileCallback(profile) {
var emailAddress;
// Filter the emails object to find the user's primary account, which might
// not always be the first in the array. The filter() method supports IE9+.
emailAddress = profile['emails'].filter(function (v) {
return v.type === 'account'; // Filter out the primary email
})[0].value; // get the email from the filtered results, should always be defined.
var domain = emailAddress.replace(/.*@/, "");
if ("xyz.com" == domain) {
window.location.href = "google_login.php?xyzEmailAddress=" + emailAddress;
} else {
alert(emailAddress + ' is not a recognized xyz staff member email address.');
}
}
</script>
</body>
</html>
<?php
// This code is called from the javascript on the login screen only
// AFTER Google authorization has succeeded
// Google_Client is as defined at
// https://github.com/google/google-api-php-client/blob/master/src/Google/Client.php
$googleClient = new Google_Client ();
$googleClient->setRedirectUri('postmessage');
$googleClient->authenticate($_SESSION['GoogleAuthorizationCode']);
最佳答案
需要从此处的左侧面板添加/启用 API https://console.developers.google.com .我添加的 API 是“google+ API”和“gmail API”。我试过了,它对我有用。
关于javascript - Google_Auth_Exception',消息为 'Error fetching OAuth2 access token, message: ' invalid_grant',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26140533/
我尝试将 python 2.x 代码移植到 python 3。我正在努力解决的问题是 from mimetools import Message ... headers = Message(Strin
我有一个输入组件,它有三种类型的验证(required、validatorMessage、converterMessage),这个输入有自己的消息图标,整个表单有一个消息组件来显示所有组件的所有消息,
我有一个使用消息代理 (activemq) 的带有 spring 和 websockets 的 webapp。 这是我的配置类: @Configuration @EnableWebSocketMess
据我了解mbox Python 3.6 标准库中的类生成 email.message.Message 类型的旧式消息对象. 较新的类(class) email.message.EmailMessage
我使用的是mysql。 我有一个包含 userid、message_id、opened(true 或 false)、时间戳的消息表。 我希望所有未打开最近收到的 5 条消息的用户 这就是我现在拥有的:
我是 Android 的新手,发现要不断更新主视图,我必须创建一个线程来处理各种进程,然后将更新传回主视图。我决定使用 Handler 类来执行此操作。此示例中的 View 有一个用于激活代码的按钮和
我遇到了重定向符号的不同位置( > , &2 message message echo message >&2 message >&2 echo message message 对于所有表单,我得到了
我想使用 firebase 云函数发送通知,所以我尝试使用 firebase.messaging().getToken() 获取 token ,但我不断收到错误消息: TypeError: fireb
我实现了一个短信应用。现在我在使用 Oppo 设备时遇到了问题,因为无论何时收到消息,系统都会将默认应用程序更改为内置应用程序并显示此消息: For your messages security, S
我正在实现本指南:https://spring.io/guides/gs/centralized-configuration/关于Spring Cloud配置。 服务器: @EnableConfigS
我想在“匹配”之后,向所有比赛发送介绍信息。你知道一种轻松发送的方法吗?(我使用 Bluestacks) 提前致谢。问候。 最佳答案 只需传递 session.send()在session.dialo
在我们的应用程序中,我们使用 kafka 并有一个像这样的 Spring Cloud 输入流 @Component public interface SomeChannel { @Input(
这周我在通过 Node.js 库(代码相同,库版本相同等)向我的 iOS 设备发送消息时遇到了很多内部错误 很难调试,因为有时它会起作用。当我使用 for 循环发送 10 条消息时,我的设备将收到 3
我目前正在记录错误并希望获得尽可能多的描述性细节。我知道我可以捕获许多不同类型的异常,但 Exception.Message 之间有什么区别?和 Exception.InnerException.Me
我创建了一个映射到 MyBean.beansField 的表单。我使用 javax.validation.NotNull 注释来确保必须输入它。到目前为止一切正常,但错误消息如下所示: beansFi
我正在研究 Azure 服务总线。我的服务总线队列正在处理一条消息 3 次。我的消息锁定时间是5分钟。每条消息最多处理 2 分钟,但我不知道为什么队列会选择相同的消息并发送到处理,而重复的消息仅在 5
我正在使用最新的快速修复版本,即 1.6.0。我已经有针对 1.5.3 编写的代码,我想做的是将其升级到 1.6.0 我遇到的问题是,当我使用破解(msg,sessionID)方法时,它会抛出quic
当我调用 grails message()函数来查找和评估消息 key 对,它无法评估参数。 在我的 Controller 中,我调用消息函数: rejectWithError(message(cod
我使用一个小型 Spring 应用程序,其中数据库中的值很少,我想使用可变调用来检索它们。 API 在这里, @RestController @RequestMapping("/api/v1/prod
我在想在用以更好的方式,像这样: Please inform us about: 这个想法是以一种不同的方式向用户展示消息,具有更多的风格。这可能吗? 最佳答案 它们可通过 Fac
我是一名优秀的程序员,十分优秀!