Co należy zrobić przed dokonaniem zakupu, to sprawdzić, czy użytkownik jest tym, którego się spodziewa, poprzez bezpieczne przekazanie identyfikatora użytkownika z klienta na serwer i zweryfikowanie go pod kątem identyfikatora użytkownika dla zapisanych poświadczeń. Zapewnia to dodatkową ochronę przed atakami typu "powtórka", gdy atakujący podszywa się pod sesję użytkownika i jest najbardziej odpowiednią sprawą przed zaakceptowaniem płatności od użytkownika.
Nie będę polegać wyłącznie na walidacji użytkownika jako mechanizmie ochrony przed oszustwami. Powinieneś użyć bezpiecznego systemu płatności, takiego jak Google Commerce platform i postępować zgodnie z the best practices for commerce.
Jako przypomnienie, punkt końcowy OAuth2 v2 powinien być używany do sprawdzania tokena za każdym razem, gdy inicjowane są buforowane poświadczenia. Sprawdzenie każdego żądania wydaje się nieco przesadzone, ponieważ powinno się używać poświadczeń przechowywanych w pamięci podręcznej, które zostały już sprawdzone i zapisane po stronie serwera. Co najwyżej można przeprowadzić sprawdzanie podczas aktualizowania tokena dostępu, ale jeśli ufasz tokenowi odświeżania, powinieneś być wystarczająco bezpieczny, jeśli wykonasz sprawdzenia podczas tworzenia konta i ustawisz token odświeżania.
Następujące kroki są podejmowane oprócz weryfikacji identyfikatora użytkownika podczas tworzenia konta:
- Sprawdź, czy klient jest kim można się spodziewać, że będzie. Chroni przed fałszywymi tokenami dostępu przekazywanymi do Twojej aplikacji w celu efektywnego wysyłania żądań w imieniu atakującego przy użyciu limitu.
- Sprawdź, czy konto zostało utworzone przez aplikację, to protects you and your users against cross-site request forgery w przypadkach, gdy dodatkowe konta są tworzone w imieniu użytkownika.
Jak wspomniano w Twoim postingu, przykładowy kod w wersji the Google+ quickstarts powinien wystarczająco demonstrować sposób przeprowadzania tych kontroli w różnych językach programowania w celu autoryzacji konta.
W HTML/klient JS poniższy kod pokazuje, gdzie identyfikator użytkownika (wartość, w przeciwieństwie do specjalnego napisu „ja”) jest pobierany na przejście do metody connect zweryfikować 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>'));
}
});
... a poniższy kod zawiera identyfikator Google+.
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
});
}
Odpowiedni kod wykonywania tych kontroli w próbce Java jest następujący:
// 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());
}
W próbek, ClientID przyszedł z konsoli Google API i będzie odrębny dla danej aplikacji.
Opublikowaliśmy pokrewne pytanie, ponieważ uważam, że standardowym sposobem zrobienia tego za pomocą interfejsu API Facebooka jest użycie parametru signed_request, ale wygląda na to, że Google nie ma odpowiednika. http://stackoverflow.com/questions/15395142/does-google-javascript-api-have-an-equivalent-to-facebooks-signed-request –