python #python-2.7 #python-requests
#python #аутентификация #перенаправление #python-запросы
Вопрос:
У меня есть быстрый вопрос относительно базовой аутентификации HTTP после перенаправления.
Я пытаюсь войти на веб-сайт, который по оперативным соображениям немедленно перенаправляет меня на центральный сайт входа, используя ответ HTTP 302. В моем тестировании кажется, что модуль запросов не отправляет мои учетные данные на центральный сайт входа после перенаправления. Как видно из приведенного ниже фрагмента кода, я вынужден извлечь URL-адрес перенаправления из объекта ответа и повторить попытку входа в систему.
Мой вопрос прост:
есть ли способ принудительно отправлять запросы на повторную отправку учетных данных для входа после перенаправления вне хоста?
По соображениям переносимости я бы предпочел не использовать файл .netrc. Кроме того, поставщик веб-сайта сделал url_login статическим, но не сделал такого заявления о url_redirect.
Спасибо за ваше время!
ФРАГМЕНТ КОДА
import requests
url_login = '<url_login>'
myauth = ('<username>', '<password')
login1 = requests.request('get', url_login, auth=myauth)
# this login fails; response object contains the login form information
url_redirect = login1.url
login2 = requests.request('get', url_redirect, auth=myauth)
# this login succeeds; response object contains a welcome message
Обновить
Вот более конкретная версия общего кода выше.
- Первый
request()
возвращает ответ HTTP 200 и содержит информацию о форме в текстовом поле. - Второй
request()
возвращает ответ HTTP 401 с'HTTP Basic: Access denied.'
в его текстовом поле.
(Конечно, вход в систему выполняется успешно, если предоставлены действительные учетные данные.)
Опять же, мне интересно, смогу ли я достичь желаемого входа в систему только одним вызовом requests.request()
.
import requests
url_login = 'http://cddis-basin.gsfc.nasa.gov/CDDIS_FileUpload/login'
myauth = ('<username>', '<password>')
with requests.session() as s:
login1 = s.request('get', url_login, auth=myauth)
url_earthdata = login1.url
login2 = s.request('get', url_earthdata, auth=myauth)
Комментарии:
1. Можете ли вы поделиться URL-адресом?
2. Конечно, URL- адрес cddis-basin.gsfc.nasa.gov/CDDIS_FileUpload/login , и более подробную информацию о том, что я пытаюсь сделать, можно найти по адресу cddis.gsfc.nasa.gov/Data_and_Derived_Products /. … Я хотел, чтобы мой вопрос был как можно более общим, но если это поможет, продолжайте!
3. Я думаю, вам нужен сеанс, вы пытаетесь имитировать логику curl?
4. Да, я пытаюсь имитировать логику cURL. В моей собственной реализации я использую сеанс для обработки файлов cookie. Однако конкретная проблема, о которой я интересуюсь (сбой аутентификации после повторного перенаправления), не зависит от использования объекта сеанса.
Ответ №1:
Моим решением для этого было бы использование «Сеанса». Вот как вы можете реализовать сеанс.
import requests
s = requests.session()
url_login = "<loginUrl>"
payload = {
"username": "<user>",
"password": "<pass>"
}
req1 = s.post(url_login, data=payload)
# Now to make sure you do not get the "Access denied", use the same session variable for the request.
req2 = s.get(url_earthdata)
Это должно решить вашу проблему.
Комментарии:
1. Спасибо, что порекомендовали использовать сеанс — я соответствующим образом обновил пример кода в своем сообщении. К сожалению, URL-адрес, на который вы ссылаетесь в своей второй команде,
url_earthdata
, заранее неизвестен. URL, указанный для входа в систему,url_login
, возвращает перенаправление HTTP 302 на адрес, который не гарантированно будет статическим. Я хотел бы отправить свои учетные данные на второй URL-адрес без явного извлечения URL-адреса с первой попытки (url_earthdata = login1.url
) и выполнения второй попытки (login2 = s.request('get', url_earthdata, auth=myauth)
)2. в этом случае вы можете использовать «allow_redirects = False» в первом запросе, чтобы получить перенаправляющий URL. Просто просмотрите заголовки первого запроса для «url_earthdata», который вы ищете. Например, >>> req1 = s.post(url_login, data=полезная нагрузка, allow_redirects=False) >>> url_earthdata = req1.headers[«<URL_KEY>»]
3. Хорошо, это хороший совет, но для этого все равно требуется два отдельных HTTP-запроса. Поскольку я хотел узнать больше о повторной отправке учетных данных для входа после перенаправления вне хоста — т. Е. Для достижения моего входа в систему только с помощью одного запроса — я могу принять этот ответ, если вы отвлекаете внимание от сеансов и вместо этого подчеркиваете, что «нет, вы не можете сделать это в одном запросе». Спасибо за ваше время!
4. Целью HTTP 302 является перенаправление URL . Ответ с кодом состояния 302 предоставляет URL-адрес перенаправления в его заголовке под ключом местоположения , который должен быть запущен при выполнении другого запроса . Итак, нет , вы не можете достичь того, что пытаетесь, с помощью одного запроса .
Ответ №2:
Это невозможно с запросами по дизайну. Проблема связана с уязвимостью в системе безопасности, когда, если злоумышленник изменяет URL-адрес перенаправления, и учетные данные автоматически отправляются на URL-адрес перенаправления, учетные данные оказываются скомпрометированными. Таким образом, учетные данные удаляются из вызовов перенаправления.
На github есть тема об этом: https://github.com/psf/requests/issues/2949