Как сохранить токен 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
Сначала прочитайте этот ответ из ветки. Теперь рассмотрим вторую половину вопроса (основываясь на комментариях):
Как использовать токен обновления?
- Создайте новый запрос POST (проще всего продублировать созданный вами запрос на получение access_token).
![enter image description here]()
- В теле удалите
username
и password
. Замените grant_type
на "refresh_token". Добавьте refresh_token
со значением "{{refresh_token}}", которое является ссылкой на переменную, которая была создана при первой авторизации (вы не забыли прочитать этот ответ?)
![enter image description here]()
- Убедитесь, что в разделе "Тесты" запроса "Обновить" перезаписаны переменные Postman для access_token и refresh_token. Зачем? Потому что всякий раз, когда вы выполняете обновление, вы получаете еще один токен обновления. Если вы не захватите этот новый токен обновления, вы в конечном итоге будете использовать старый токен обновления, и API его отклонит. Затем вам нужно будет заново выполнить все это с первого шага (т.е. из этого ответа).
![enter image description here]()
- Теперь, когда срок действия вашей авторизации истекает, вам не нужно запускать исходный запрос, содержащий ваше имя пользователя и пароль. Вы можете постоянно обновлять, используя запрос, который мы только что создали. Это особенно полезно, когда вы сотрудничаете и вам нужно предоставить общий доступ к API, но вы не хотите делиться именами пользователей и паролями.
НТН!