Как сохранить токен OAuth2 (или использовать токен обновления) в коллекциях Postman?

Цель

Уметь запускать коллекцию без прохождения процесса авторизации каждого вызова индивидуально до запуска коллекции.

Что я пытался/заметил

  • При использовании помощника авторизации OAuth2 в Postman я не обнаружил метод сохранения возвращенного токена обновления и, таким образом, его использовать, когда токен доступа истекает, чтобы получить новый. (Я предложил, чтобы эта функция была помещена в помощник в вопросах Postman Github.)

  • Я попытался создать несколько шагов в начале коллекции, чтобы реплицировать помощника, но не может пройти шаг, когда требуется взаимодействие с пользователем, чтобы утверждать/отклонять (что имеет смысл, поскольку это представляет угрозу безопасности в противном случае). Однако я не могу понять, как запросить пользователя, как это делает помощник OAuth2.

  • Я оправдал мои ожидания в отношении токена обновления и думал, что могу просто запустить проверку подлинности в первом тесте в списке, сохраняя токен доступа как-то в глобальной или переменной окружения, и затем используя этот токен во всех последующих тестах, но я не нашел способ сохранить токен доступа, сгенерированный с помощью помощника OAuth2.

Я хотел бы знать, есть ли решение для этого, что приводит к тому, что коллекции могут запускаться с минимальными усилиями, введенными в авторизацию. Это становится более важным с большим количеством тестов, написанных в коллекции, которые все используют авторизацию OAuth2.

Боковое примечание. Я использую клиентский почтовый клиент Postman, если у меня есть другие клиенты, о которых я не знаю.

Ответ 1

Я нашел ответ здесь, на github.

Сначала настройте эти переменные среды:

  • url: (конечная точка API)
  • access_token: (пусто)
  • refresh_token: (пусто)
  • client_id: (ваш client_id)
  • client_secret: (ваш client_secret)
  • username: (ваше имя пользователя)
  • password: (ваш пароль)

Затем создайте новый вызов, который получает access_token, используя password grant_type.

В моем случае я отправляю сообщение {{url}}/access_token. Отправляется с этим вызовом следующая информация как пара <ключ/значение > t211 > , указанная на вкладке "Тело":

  • grant_type: password
  • username: {{username}}
  • password: {{password}}
  • client_id: {{client_id}}
  • client_secret: {{client_secret}}

Отправка этого POST приведет к чему-то вроде этого ответа:

{
  "access_token": "kciOMpcmRcGTKfoo",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "DMGAe2TGaFbar"
}

Затем на вкладке "Тесты" я добавил следующий код для назначения двух переменных среды: access_token и refresh_token.

var data = JSON.parse(responseBody);
postman.setEnvironmentVariable("access_token", data.access_token);
postman.setEnvironmentVariable("refresh_token", data.refresh_token);

ПРИМЕЧАНИЕ. Я также поставил тест там, чтобы убедиться, что хотя бы этот вызов работал правильно, хотя это не имеет ничего общего с исходным вопросом:

var jsonData = JSON.parse(responseBody);
tests["token_type is Bearer"] = jsonData.token_type === "Bearer";

Теперь любой новый вызов, который я создаю, может использовать access_token, сгенерированный этим первым вызовом, в качестве переменной среды следующим образом: {{access_token}}. В моем случае я перехожу на вкладку "Заголовки" в вызове/тесте и добавляю этот ключ/пару:

  • Authorization: Bearer {{access_token}}

Бонусные баллы: здесь я не привел пример, но теоретически я мог бы добавить предварительный запрос script, который проверяет текущий (не пустой) access_token на API и, если он терпит неудачу, получит новый с использованием данного (не пустого) refresh_token. Это сделает так, что мне не придется беспокоиться о истечении срока действия токенов доступа.

Что все сказано, я не люблю это решение, потому что он требует добавления этого первого вызова access_token в каждую подпапку в моей коллекции, потому что, если я хочу запускать только подпапку, а не коллекцию в целом, я нужно убедиться, что у меня есть новый access_token. Это не означает, что все тесты будут терпеть неудачу, если истечет срок действия access_token. Если вы никогда не запускаете подпапки отдельно в своем проекте Runner, вы можете уйти с созданием только одного вызова access_token и установки его в качестве первого вызова для запуска в коллекции.

Но по этой причине я не буду отмечать это как правильный ответ. Я предполагаю, что есть лучший ответ, чем то, что я придумал, - в идеале, когда мне не нужно дублировать один и тот же вызов/тест access_token в каждую подпапку, но получайте выгоду от автоматических, неинтерактивных тесты с гибкостью запуска подпапки сами по себе или коллекции в целом.

Ответ 2

Итак, сначала введите URL-адрес маркера OAUTH, щелкните вкладку "Тело" и заполните эти параметры POST: client_id, grant_type, имя пользователя, пароль, переопределение.

введите описание изображения здесь

Затем нажмите вкладку "Тест", введите этот текст и нажмите "Отправить":

var data = JSON.parse(responseBody);
postman.setGlobalVariable("access_token", data.access_token);
postman.setGlobalVariable("refresh_token", data.refresh_token);

введите описание изображения здесь

Затем введите один из ваших URL-адресов приложений, нажмите вкладку "Заголовки" и введите параметр "Авторизация" со значением "На предъявителя" {{access_token}}. Затем нажмите "Отправить".

введите описание изображения здесь

Voila!

Ответ 3

Оба других ответа верны. Но есть и другой способ, которым это можно сделать, и не требующий дополнительного запроса. Этот метод использует сценарий pre-request для запроса, которому нужен access_token. Вы можете использовать pm.sendRequest как pm.sendRequest в pm.sendRequest -sandbox-api

Из сценария предварительного запроса просто отправьте запрос по URL-адресу авторизационного токена. Отправьте все учетные данные и токен обновления. В ответ вы получите токен доступа, который затем можно сохранить в среде или просто в памяти, а затем использовать.

Пример кода, который я сделал суть здесь https://gist.github.com/harryi3t/dd5c61451206047db70710ff6174c3c1

// Set all these variables in an environment or at collection level
let tokenUrl = pm.variables.get('tokenUrl'),
    clientId = pm.variables.get('clientId'),
    clientSecret = pm.variables.get('clientSecret'),
    refreshToken = pm.variables.get('refreshToken'),
    requestOptions = {
      method: 'POST',
      url: tokenUrl,
      body: {
        mode: 'formdata',
        formdata: [
            {
                key: 'grant_type',
                value: 'refresh_token'
            },
            {
                key: 'client_id',
                value: clientId
            },
            {
                key: 'client_secret',
                value: clientSecret
            },
            {
                key: 'refresh_token',
                value: refreshToken
            }
        ]
      }
    };

console.log({ requestOptions });

pm.sendRequest(requestOptions, (err, response) => {
  let jsonResponse = response.json(),
      newAccessToken = jsonResponse.access_token;

  console.log({ err, jsonResponse, newAccessToken })

  // If you want to persist the token
  pm.environment.set('accessToken', newAccessToken);

  // Or if you just want to use this in the current request and then discard it
  pm.variables.set('accessToken', newAccessToken);
});

Теперь, когда запрос отправляется, будет присутствовать переменная accessToken, которую вы можете использовать в своем запросе следующим образом: enter image description here

Примечание: в Oauth2 есть 4 типа грантов. Два из них (Auth code & Implicit) требуют взаимодействия с браузером, который не может быть автоматизирован. Но если сервер предоставляет токен обновления, приведенный выше скрипт может помочь вам получить токен доступа. Два других типа (учетные данные клиента и пароль) не требуют взаимодействия с браузером. Таким образом, они могут быть автоматизированы из сценариев. Если вы используете client_credentials, вы можете настроить вышеприведенный скрипт, чтобы получить code от authUrl а затем получить access_token от AuthTokenUrl.

Ответ 4

Сначала прочитайте этот ответ из ветки. Теперь рассмотрим вторую половину вопроса (основываясь на комментариях):

Как использовать токен обновления?

  1. Создайте новый запрос POST (проще всего продублировать созданный вами запрос на получение access_token).

enter image description here

  1. В теле удалите username и password. Замените grant_type на "refresh_token". Добавьте refresh_token со значением "{{refresh_token}}", которое является ссылкой на переменную, которая была создана при первой авторизации (вы не забыли прочитать этот ответ?)

enter image description here

  1. Убедитесь, что в разделе "Тесты" запроса "Обновить" перезаписаны переменные Postman для access_token и refresh_token. Зачем? Потому что всякий раз, когда вы выполняете обновление, вы получаете еще один токен обновления. Если вы не захватите этот новый токен обновления, вы в конечном итоге будете использовать старый токен обновления, и API его отклонит. Затем вам нужно будет заново выполнить все это с первого шага (т.е. из этого ответа).

enter image description here

  1. Теперь, когда срок действия вашей авторизации истекает, вам не нужно запускать исходный запрос, содержащий ваше имя пользователя и пароль. Вы можете постоянно обновлять, используя запрос, который мы только что создали. Это особенно полезно, когда вы сотрудничаете и вам нужно предоставить общий доступ к API, но вы не хотите делиться именами пользователей и паролями.

НТН!