在执行购买之前,您可能想要做的是通过将用户标识从客户端安全地传递到服务器并根据用户标识进行验证来验证用户是否您期望他们是谁为存储的凭据。这为攻击者通过劫持他们的会话假装成为您的网站用户并在接受用户付款之前进行的最重要的检查提供了额外的防范重播攻击。
我不会仅依靠用户验证作为防范欺诈的机制。您应该使用安全支付系统,如Google Commerce platform,并按照the best practices for commerce。
提醒一下,每次缓存的凭据初始化时,都应该使用OAuth2 v2端点来检查您的令牌。检查每个请求似乎有点过分,因为您应该使用已经验证并存储在服务器端的缓存凭据。在更新访问令牌时,至多可以执行检查,但如果您信任刷新令牌,则在创建帐户并设置刷新令牌时执行检查时应该足够安全。
以下步骤都采取了在除了用户ID验证建立帐户时:
- 验证客户端是你希望它是谁。这可以防止伪造的访问令牌被传递到您的应用,以便代表攻击者使用您的配额有效发出请求。
- 确认该帐户是由您的应用程序创建的,该帐户是在代表用户创建其他帐户的情况下创建的。
正如您的链接帖子中所提到的,the Google+ quickstarts中的示例代码应该充分说明如何使用多种编程语言对帐户授权执行这些检查。
中的HTML/JS客户端,下面的代码示出了用户ID(值,而不是特殊的字符串“我”),以传递给连接方法来验证的Google+ userID是检索到:
var request = gapi.client.plus.people.get({'userId' : 'me'});
request.execute(function(profile) {
$('#profile').empty();
if (profile.error) {
$('#profile').append(profile.error);
return;
}
helper.connectServer(profile.id);
$('#profile').append(
$('<p><img src=\"' + profile.image.url + '\"></p>'));
$('#profile').append(
$('<p>Hello ' + profile.displayName + '!<br />Tagline: ' +
profile.tagline + '<br />About: ' + profile.aboutMe + '</p>'));
if (profile.cover && profile.coverPhoto) {
$('#profile').append(
$('<p><img src=\"' + profile.cover.coverPhoto.url + '\"></p>'));
}
});
...以下代码显示正在传送的Google+ ID。
connectServer: function(gplusId) {
console.log(this.authResult.code);
$.ajax({
type: 'POST',
url: window.location.href + '/connect?state={{ STATE }}&gplus_id=' +
gplusId,
contentType: 'application/octet-stream; charset=utf-8',
success: function(result) {
console.log(result);
helper.people();
},
processData: false,
data: this.authResult.code
});
}
在Java样品中执行这些检查相关的代码如下:
// Check that the token is valid.
Oauth2 oauth2 = new Oauth2.Builder(
TRANSPORT, JSON_FACTORY, credential).build();
Tokeninfo tokenInfo = oauth2.tokeninfo()
.setAccessToken(credential.getAccessToken()).execute();
// If there was an error in the token info, abort.
if (tokenInfo.containsKey("error")) {
response.status(401);
return GSON.toJson(tokenInfo.get("error").toString());
}
// Make sure the token we got is for the intended user.
if (!tokenInfo.getUserId().equals(gPlusId)) {
response.status(401);
return GSON.toJson("Token's user ID doesn't match given user ID.");
}
// Make sure the token we got is for our app.
if (!tokenInfo.getIssuedTo().equals(CLIENT_ID)) {
response.status(401);
return GSON.toJson("Token's client ID does not match app's.");
}
// Store the token in the session for later use.
request.session().attribute("token", tokenResponse.toString());
return GSON.toJson("Successfully connected user.");
} catch (TokenResponseException e) {
response.status(500);
return GSON.toJson("Failed to upgrade the authorization code.");
} catch (IOException e) {
response.status(500);
return GSON.toJson("Failed to read token data from Google. " +
e.getMessage());
}
在该样品中ClientID的从谷歌API控制台来了,将是不同的应用程序。
我发布了一个相关的问题,因为我认为使用Facebook API执行此操作的标准方法是使用signed_request参数,但Google似乎没有相应的参数。 http://stackoverflow.com/questions/15395142/does-google-javascript-api-have-an-equivalent-to-facebooks-signed-request – 2013-03-14 16:57:42