Как отправить & ldquo; Войти с помощью Google & rdquo; ссылку в теле письма? [Дубликат]

В следующем примере, который я написал, показано, как

  • обрабатывать асинхронные HTTP-вызовы;
  • Подождать ответа от каждого вызова API;
  • Использовать шаблон promise ;
  • Используйте шаблон Promise.All для объединения нескольких HTTP-вызовов;

Этот рабочий пример является автономным. Он будет определять простой объект запроса, который использует объект window XMLHttpRequest для совершения вызовов. Он будет определять простую функцию, чтобы дождаться завершения кучи обещаний.

Контекст. В этом примере запрашивается конечная точка Spotify Web API для поиска объектов playlist для заданного набора строк запроса:

[
 "search?type=playlist&q=%22doom%20metal%22",
 "search?type=playlist&q=Adele"
]

Для каждого элемента новый Promise запустит блок - ExecutionBlock, проанализирует результат, заплатит новый набор обещаний на основе массива результатов, который представляет собой список объектов Spotify user и выполняет новый HTTP-вызов в ExecutionProfileBlock асинхронно.

Затем вы можете увидеть вложенную структуру Promise, которая позволяет вам генерировать множественные и полностью асинхронные вложенные HTTP-вызовы и присоединять результаты к каждому подмножеству вызовов через Promise.all.

NOTE Recent Spotify search API-интерфейсам потребуется указать токен доступа в заголовках запроса:

-H "Authorization: Bearer {your access token}" 

Итак, вы должны запустить следующий пример, вам нужно поместить маркер доступа в заголовки запроса:

var spotifyAccessToken = "YourSpotifyAccessToken";
var console = {
    log: function(s) {
        document.getElementById("console").innerHTML += s + "
" } } // Simple XMLHttpRequest // based on https://davidwalsh.name/xmlhttprequest SimpleRequest = { call: function(what, response) { var request; if (window.XMLHttpRequest) { // Mozilla, Safari, ... request = new XMLHttpRequest(); } else if (window.ActiveXObject) { // Internet Explorer try { request = new ActiveXObject('Msxml2.XMLHTTP'); } catch (e) { try { request = new ActiveXObject('Microsoft.XMLHTTP'); } catch (e) {} } } // State changes request.onreadystatechange = function() { if (request.readyState === 4) { // Done if (request.status === 200) { // Complete response(request.responseText) } else response(); } } request.open('GET', what, true); request.setRequestHeader("Authorization", "Bearer " + spotifyAccessToken); request.send(null); } } //PromiseAll var promiseAll = function(items, block, done, fail) { var self = this; var promises = [], index = 0; items.forEach(function(item) { promises.push(function(item, i) { return new Promise(function(resolve, reject) { if (block) { block.apply(this, [item, index, resolve, reject]); } }); }(item, ++index)) }); Promise.all(promises).then(function AcceptHandler(results) { if (done) done(results); }, function ErrorHandler(error) { if (fail) fail(error); }); }; //promiseAll // LP: deferred execution block var ExecutionBlock = function(item, index, resolve, reject) { var url = "https://api.spotify.com/v1/" url += item; console.log( url ) SimpleRequest.call(url, function(result) { if (result) { var profileUrls = JSON.parse(result).playlists.items.map(function(item, index) { return item.owner.href; }) resolve(profileUrls); } else { reject(new Error("call error")); } }) } arr = [ "search?type=playlist&q=%22doom%20metal%22", "search?type=playlist&q=Adele" ] promiseAll(arr, function(item, index, resolve, reject) { console.log("Making request [" + index + "]") ExecutionBlock(item, index, resolve, reject); }, function(results) { // Aggregated results console.log("All profiles received " + results.length); //console.log(JSON.stringify(results[0], null, 2)); ///// promiseall again var ExecutionProfileBlock = function(item, index, resolve, reject) { SimpleRequest.call(item, function(result) { if (result) { var obj = JSON.parse(result); resolve({ name: obj.display_name, followers: obj.followers.total, url: obj.href }); } //result }) } //ExecutionProfileBlock promiseAll(results[0], function(item, index, resolve, reject) { //console.log("Making request [" + index + "] " + item) ExecutionProfileBlock(item, index, resolve, reject); }, function(results) { // aggregated results console.log("All response received " + results.length); console.log(JSON.stringify(results, null, 2)); } , function(error) { // Error console.log(error); }) ///// }, function(error) { // Error console.log(error); });

Я подробно рассмотрел это решение здесь .

17
задан Andy0708 29 May 2015 в 10:03
поделиться

2 ответа

Эта функция просто генерирует значение состояния String (по умолчанию UUID.randomUUID().toString()), помещает его в сеанс и передает его поставщику в качестве параметра «состояние» в запросе авторизации. Ожидается, что провайдер передаст его обратно на обратный вызов. Если сохраненное состояние соответствует тому, которое было в обратном вызове, тогда мы хороши. Если они не совпадают, тогда вы видите исключение, которое вы упомянули там.

Это должно работать, но да, я вижу, что у вас проблемы. Я также нашел эту ссылку, которая может быть стоит посмотреть: https://github.com/spring-projects/spring-social-facebook/issues/103

2
ответ дан jester 28 August 2018 в 00:36
поделиться

Параметр state предотвращает атаки CSRF в OAuth2.

Идея:

  • Ваше приложение добавляет параметр state к запросу, который он делает для сервер аутентификации (в данном случае Facebook)
  • Сервер аутентификации повторяет точное значение этого параметра state обратно к вам в ответе
  • Затем вы проверяете, соответствуют ли они

. Это звучит бессмысленно ... но это не позволяет злоумышленникам совершать ваши запросы на действия с клиентом, которые он не инициировал.

Это подробно описывает это:

http://www.twobotechnologies.com/blog/2014/02/importance-of-state-in-oauth2.html

Spring Social обрабатывает все это для вас: генерирует новый случайный state для каждого запроса и автоматически пытается сопоставить его с значением в ответе.

Таким образом, вы не можете запретите это :, и вы не хотите: это могут быть неудачные попытки атаки - и в этих случаях вы хотите выполнить эту ошибку.

[g1 4] Для случаев, которые вы опубликовали, может просто ошибочно обрабатывать параметр state Spring Social или серверами аутентификации Facebook.

Но для вашего part, вы должны обрабатывать исключение, как если бы это была настоящая попытка атаки: предупреждения журнала / оповещения людей и т. д.

7
ответ дан Mr Spoon 28 August 2018 в 00:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: