在執行購買之前,您可能想要做的是通過將用戶標識從客戶端安全地傳遞到服務器並根據用戶標識進行驗證來驗證用戶是否您期望他們是誰爲存儲的憑據。這爲攻擊者通過劫持他們的會話假裝成爲您的網站用戶並在接受用戶付款之前進行的最重要的檢查提供了額外的防範重播攻擊。
我不會僅依靠用戶驗證作爲防範欺詐的機制。您應該使用安全支付系統,如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