You could have wrapped this in a function and used a decorator to evaluate the response and retry the auth on 401. Then you only need to decorate any function that requires this re-auth logic….
Update:
As requested, a code example. I’m afraid this one is an old piece of code, Python 2 based, but you’ll get the idea. This one will retry an http call a number of times as defined in settings.NUM_PLATFORM_RETRIES
and will call a refresh_token
on auth failures. you can adjust the use case and result to whatever.
You can then use this decorator around methods:
@retry_on_read_error
def some_func():
do_something()
def retry_on_read_error(fn):
"""
Retry Feed reads on failures
If a token refresh is required it is performed before retry.
This decorator relies on the model to have a refresh_token method defined, othewise it will fail
"""
@wraps(fn)
def _wrapper(self, *args, **kwargs):
for i in range(settings.NUM_PLATFORM_RETRIES):
try:
res = fn(self, *args, **kwargs)
try:
_res = json.loads(res)
except ValueError:
# not a json response (could be local file read or non json data)
return res
if 'error' in _res and _res['error']['status'] in (401, 400):
raise AccessRefusedException(_res['error']['message'])
return res
except (urllib2.URLError, IOError, AccessRefusedException) as e:
if isinstance(e, AccessRefusedException):
self.refresh_token()
continue
raise ApiRequestFailed(
"Api failing, after %s retries: %s" % (settings.NUM_PLATFORM_RETRIES, e), args, kwargs
)
return _wrapper
Solution 1:[1]
It doesn’t get any less ugly than this, I think:
import requests
from requests.auth import HTTPBasicAuth
response = requests.get('http://your_url')
if response.status_code == 401:
response = requests.get('http://your_url', auth=HTTPBasicAuth('user', 'pass'))
if response.status_code != 200:
# Definitely something's wrong
Solution 2:[2]
You could have wrapped this in a function and used a decorator to evaluate the response and retry the auth on 401. Then you only need to decorate any function that requires this re-auth logic….
Update:
As requested, a code example. I’m afraid this one is an old piece of code, Python 2 based, but you’ll get the idea. This one will retry an http call a number of times as defined in settings.NUM_PLATFORM_RETRIES
and will call a refresh_token
on auth failures. you can adjust the use case and result to whatever.
You can then use this decorator around methods:
@retry_on_read_error
def some_func():
do_something()
def retry_on_read_error(fn):
"""
Retry Feed reads on failures
If a token refresh is required it is performed before retry.
This decorator relies on the model to have a refresh_token method defined, othewise it will fail
"""
@wraps(fn)
def _wrapper(self, *args, **kwargs):
for i in range(settings.NUM_PLATFORM_RETRIES):
try:
res = fn(self, *args, **kwargs)
try:
_res = json.loads(res)
except ValueError:
# not a json response (could be local file read or non json data)
return res
if 'error' in _res and _res['error']['status'] in (401, 400):
raise AccessRefusedException(_res['error']['message'])
return res
except (urllib2.URLError, IOError, AccessRefusedException) as e:
if isinstance(e, AccessRefusedException):
self.refresh_token()
continue
raise ApiRequestFailed(
"Api failing, after %s retries: %s" % (settings.NUM_PLATFORM_RETRIES, e), args, kwargs
)
return _wrapper
Solution 3:[3]
You can use something like this
# 401 retry strategy
import requests
from requests import Request, Session, RequestException
class PreparedRequest:
"""
Class to make Http request with 401 retry
"""
failedRequests = []
defaultBaseUrl = "https://jsonplaceholder.typicode.com"
MAX_RETRY_COUNT = 0
def __init__(self, method, endpoint,
baseurl=defaultBaseUrl, headers=None, data=None, params=None):
"""
Constructor for PreparedRequest class
@param method: Http Request Method
@param endpoint: endpoint of the request
@param headers: headers of the request
@param data: data of request
@param params: params of the request
"""
self.method = method
self.url = baseurl + endpoint
self.headers = headers
self.data = data
self.params = params
self.response = None
def send(self):
"""
To send http request to the server
@return: response of the request
"""
req = Request(method=self.method, url=self.url, data=self.data,
headers=self.headers,params=self.params)
session = Session()
prepared = session.prepare_request(req)
response = session.send(prepared)
if response.status_code == 200:
PreparedRequest.failedRequests.append(self)
PreparedRequest.refresh_token()
elif response.status_code == 502:
raise Exception(response.raise_for_status())
else:
self.response = session.send(prepared)
@staticmethod
def refresh_token():
if PreparedRequest.MAX_RETRY_COUNT > 3:
return
print("Refreshing the token")
# Write your refresh token strategy here
PreparedRequest.MAX_RETRY_COUNT += 1
total_failed = len(PreparedRequest.failedRequests)
for i in range(total_failed):
item = PreparedRequest.failedRequests.pop()
item.send()
r = PreparedRequest(method="GET", endpoint="/todos/")
r.send()
print(r.response.json())
Answer by Bryson Massey
Why were the Apollo 12 astronauts tasked with bringing back part of the Surveyor 3 probe?
,
Stack Overflow for Teams
Where developers & technologists share private knowledge with coworkers
,Thanks for contributing an answer to Stack Overflow!,
Shift to remote work prompted more cybersecurity questions than any breach
It doesn’t get any less ugly than this, I think:
import requests
from requests.auth import HTTPBasicAuth
response = requests.get('http://your_url')
if response.status_code == 401:
response = requests.get('http://your_url', auth=HTTPBasicAuth('user', 'pass'))
if response.status_code != 200:
# Definitely something's wrong
Answer by Aisha Berger
Getting 401 unauthorized error python after trying everything,Hi All, please help. I tried everything still getting 401 unauthorized error in python. Below is my code.,because I do know little bit of scraping and when trying with Selenium and BeautifulSoup (after opening the URL) it still gives me 401 unauthorized error.,Please help. I am exhausted trying every page on this community and you tube videos, nothing is working
Hi All, please help. I tried everything still getting 401 unauthorized error in python. Below is my code.
url = 'https://jira.mycompanyname.org/rest/api/2/issue/XYZ-85'server = 'https://jira.mycompanyname.org'headers = {'Accept':'application/json','Content-Type':'application/json','Authorization': 'Basic [base64 encoded string of my office email id:auth token]'}options = {'server':sever}query = {'jql':'project=XYZ'}response = requests.get(url,headers=headers,params=query)print(response.text)
Answer by Molly Velasquez
The 401 Error in Chrome,The 401 status code in the developer console in Chrome,The Internet Engineering Task Force (IETF) defines the error 401 Unauthorized as:,If you encounter an error code in the 400s, you know you’re dealing with a client-side (or browser-side) issue. While the problem may be happening within your browser, however, it doesn’t necessarily always mean that’s the culprit, which we’ll explain in more detail later.
Another method you can try to resolve the 401 error is flushing your Domain Name Server (DNS). While this is a rarer issue, it can be a possible cause, so it’s worth giving it a try if the first two solutions don’t work.
To do this in Windows, click on the Start button and type cmd
into the search bar. Hit Enter, and the Command Prompt will open. Copy and paste the command ipconfig/flushdns
, and then hit Enter again:
cmd
Another method you can try to resolve the 401 error is flushing your Domain Name Server (DNS). While this is a rarer issue, it can be a possible cause, so it’s worth giving it a try if the first two solutions don’t work.
To do this in Windows, click on the Start button and type cmd
into the search bar. Hit Enter, and the Command Prompt will open. Copy and paste the command ipconfig/flushdns
, and then hit Enter again:
ipconfig/flushdns
Answer by Evelyn Baker
What I want to do is GET from a site and if that request returns a 401, then redo my authentication wiggle (which may be out of date) and try again. But I don’t want to try a third time, since that would be my authentication wiggle having the wrong credentials. Does anyone have a nice way of doing this that doesn’t involve properly ugly code, ideally in python requests library, but I don’t mind changing.,Consider returning an http status of 401, and a JSON object detailing the reason. If you’re using jQuery, that’ll drop you to the error() callback, which you can then parse your object.,I’m not familiar with PHP anymore, but this should work for just about any environment. You may have to suppress any automatic login form redirection though. In asp.net mvc the framework will see the 401 and push the default login form back, with a status of 200.,The above code will attempt to send all the POST requests at once. Despite the intention, it will be throttled by aiohttp.ClientSession’s TCP connector which allows a maximum of 100 simultaneous connections by default. To increase or remove this limitation, you must set a custom connector on the session.
It doesn’t get any less ugly than this, I think:
import requests
from requests.auth import HTTPBasicAuth
response = requests.get('http://your_url')
if response.status_code == 401:
response = requests.get('http://your_url', auth=HTTPBasicAuth('user', 'pass'))
if response.status_code != 200:
# Definitely something's wrong
Answer by Veronica Beard
I get the exact same error when I try calling the Payment Processing Authorization endpoint.,Whenever I try to authenticate with Two Way SSL, I keep getting Error 401 code 9124. ,Using SoapUI, you can find the x-correlation-id in the Raw Tab of the response header.,I solved this by generating and importing my own CSR and private key.. I have still do not know why I could not get the auto generated own to work though.
[[email protected] visa]$ python3 hello_world.py
< GET /vdp/helloworld HTTP/1.1
< Host: sandbox.api.visa.com
< User-Agent: python-requests/2.19.1
< Accept-Encoding: gzip, deflate
< Accept: application/json
< Connection: keep-alive
< Content-Type: application/json
< Authorization: Basic NDhHVU8wV1dPVTRNRVBWWElJSDUyMTFvYTdVOFFtOTNMQlRxODk5N0JkUVY2ZVZZNDo3MUpuVWhLdjN6V0FMT2o=
<
> HTTP/1.1 401 Unauthorized
> Server: nginx
> Content-Type: application/json;charset=UTF-8
> Content-Length: 119
> X-SERVED-BY: l73c018
> X-CORRELATION-ID: 1560548141_524_207894318_l73c018_VDP_WS
> x-vdp-normalized-url: /vdp/helloworld
> X-APP-STATUS: 401
> x-vdp-authn-api-visa-id: HELLOWORLD
> X-Frame-Options: SAMEORIGIN
> X-XSS-Protection: 1; mode=block
> X-Content-Type-Options: nosniff
> Strict-Transport-Security: max-age=2592000;includeSubdomains
> Cache-Control: no-cache, no-store, must-revalidate
> Pragma: no-cache
> Expires: -1
> Date: Fri, 14 Jun 2019 21:35:41 GMT
> Connection: keep-alive
>
{"responseStatus":{"status":401,"code":"9124","severity":"ERROR","message":"Incorrect credentials supplied","info":""}}
{'responseStatus': {'status': 401, 'code': '9124', 'severity': 'ERROR', 'message': 'Incorrect credentials supplied', 'info': ''}}
#!/usr/bin/python3
import requests
from requests_toolbelt.utils import dump
def main():
URL = "<a href="https://sandbox.api.visa.com/vdp/helloworld" target="_blank">https://sandbox.api.visa.com/vdp/helloworld</a>"
CA_CERT = "/home/fedora/visa/DigiCertGlobalRootCA.pem"
CLIENT_CERT = "/home/fedora/visa/client_cert_d2288d04-5699-47ff-8d89-54cf04ec4fca.pem"
PRIVATE_KEY = "/home/fedora/visa/key_d2288d04-5699-47ff-8d89-54cf04ec4fca.pem"
USER_ID = '48GUO0WWOU4MEPVXIIH5211oa7U8Qm93LBTq8997BdQV6eVY4'
PASS = '71JnUhKv3zWALOj'
HEADERS = {'Accept': 'application/json', 'Content-Type': 'application/json'}
r = requests.get(URL,
verify = (CA_CERT),
cert = (CLIENT_CERT, PRIVATE_KEY),
headers = HEADERS,
auth = (USER_ID, PASS))
data = dump.dump_all(r)
print(data.decode('utf-8'))
print(r.json())
if __name__ == "__main__":
main()
#!/usr/bin/python3
import requests
from requests_toolbelt.utils import dump
def main():
URL = "<a href="https://sandbox.api.visa.com/acs/v1/payments/authorizations" target="_blank">https://sandbox.api.visa.com/acs/v1/payments/authorizations</a>"
CA_CERT = "/home/fedora/visa/DigiCertGlobalRootCA.pem"
CLIENT_CERT = "/home/fedora/visa/client_cert_d2288d04-5699-47ff-8d89-54cf04ec4fca.pem"
PRIVATE_KEY = "/home/fedora/visa/key_d2288d04-5699-47ff-8d89-54cf04ec4fca.pem"
USER_ID = "48GUO0WWOU4MEPVXIIH5211oa7U8Qm93LBTq8997BdQV6eVY4"
PASS = "71JnUhKv3zWALOj"
HEADERS = {'Accept': 'application/json', 'Content-Type': 'application/json'}
BODY = {
"acctInfo": {
"primryAcctNum": {
"pan": "4111111111111111",
"panExpDt": "2019-12"
}
},
"cardAcceptr": {
"clientId": "0123456789012345678901234567893"
},
"freeFormDescrptnData": "Freeformdata",
"msgIdentfctn": {
"correlatnId": "14bc567d90f23e56a8f045",
"origId": "123451234567890"
},
"msgTransprtData": "TransportData",
"transctn": {
"eComData": {
"digitalGoods": "true",
"eciCd": "5",
"xid": "EEC4567F90123A5678B0123EA67890D2345678FF"
},
"localDtTm": "2019-06-14T18:11:07",
"partialAuthInd": "true",
"posData": {
"envrnmnt": "eCom",
"panEntryMode": "OnFile",
"panSrce": "VCIND"
},
"tranAmt": {
"amt": "123.45",
"numCurrCd": "840"
},
"tranDesc": "Transactiondescription"
},
"verfctnData": {
"billngAddr": {
"addrLn": "PO Box 12345",
"postlCd": "12345"
}
},
"riskAssessmntData": {
"lowVlExmptn": "true",
"traExmptn": "true",
"trustdMerchntExmptn": "true",
"scpExmptn": "true",
"delgtdAthntctn": "true"
}
}
r = requests.post(URL,
verify = (CA_CERT),
cert = (CLIENT_CERT, PRIVATE_KEY),
headers = HEADERS,
auth = (USER_ID, PASS),
data = BODY)
data = dump.dump_all(r)
print(data.decode('utf-8'))
if __name__ == "__main__":
main()
Хочу получить данные с сайта (true или false) через запросы, а именно requests.get(‘ссылка на сайт’). Ответ приходит в виде <[Response 401]>. Я смотрел в интернете, но не понял, в основном там писали про HTTPBasicAuth (но посмотрев про это, я тоже не понял, откуда взять логин и пароль и для чего они нужны).
Как мне получить нормальный ответ, а не 401?
-
Вопрос заданболее года назад
-
804 просмотра
Если запрашиваемая страница требует аутентификации, то в запрос нужно передать соответствующую информацию, чтобы запрос был авторизован. Скорее всего это cookie аутентификация, может быть и Basic, и какие либо другие.
Так же проблема может быть в том, что не передаются нужные заголовки запроса, тот же user-agent.
Смотрите, какой запрос отправляет браузер и повторяйте его через requests.
Без кода непонятно
Пригласить эксперта
-
Показать ещё
Загружается…
22 июн. 2023, в 00:59
8000 руб./за проект
22 июн. 2023, в 00:56
8000 руб./за проект
22 июн. 2023, в 00:39
12000 руб./за проект
Минуточку внимания
I’m trying to make a request but I keep getting an error. Even tho I am logged in. I’m trying to program a bot that would thumbs up all my youtube video’s positive comments for me. I get this however
401
{
'P3P': 'CP="This is not a P3P policy! See http://support.google.com/accounts/answer/151657?hl=en for more info."',
'Server': 'YouTubeFrontEnd',
'Expires': 'Tue, 27 Apr 1971 19:44:06 EST',
'Strict-Transport-Security': 'max-age=31536000',
'X-XSS-Protection': '1; mode=block',
'Cache-Control': 'no-cache',
'Alt-Svc': 'quic=":443"; ma=2592000; v="35,34"',
'Set-Cookie': 'VISITOR_INFO1_LIVE=wzFv76wN_9Q; path=/; domain=.youtube.com; expires=Wed, 27-Sep-2017 07:28:18 GMT; httponly, YSC=Bby4n6ZsobY; path=/; domain=.youtube.com; httponly',
'Content-Type': 'text/html; charset=utf-8',
'X-Content-Type-Options': 'nosniff',
'Content-Length': '0',
'Date': 'Thu, 26 Jan 2017 19:35:18 GMT',
'X-Frame-Options': 'SAMEORIGIN'
}
Unauthorized
This is what the Chrome Network console gives me when I make the request on chrome browser.
General:
Request URL:https://www.youtube.com/comment_service_ajax?action_perform_comment_action=1
Request Method:POST
Status Code:200
FormData:
action:CAUQAhohejEydWV0eGcwb3pkaTNmbmIyMjJkcjVndW55amZmdW4zKgtvVTZVZkxHdE51STAAOABKFTExNDE1NjEzNTk0NjMwNjU3MTc2OFAA
vote_status:INDIFFERENT
session_token:QUFFLUhqbGNOaXgzaXRIN2R6ZXNVRXdvUFI2cDVzODBrd3xBQ3Jtc0ttTFdtMUViQXVzaHplM1hHYVlNVFBLSEhCMUdQTUZfX0x4cGdUa0k0TFhiekJCVFlpdlgxV2Q0NTlIQmpZakpTQ1UyUTZ4X1lFbDhTb3h3N3k4NWEyb0V6ejR2TTdRUjBIXy1KVGhqWjBzV3hLdkFvSXJIbjJZcG9xRm5YTTVQeDVzMlV1NXdoaHdKSXZDVDFkU0xHZnVPQWVyMnZPY2xTTkhuLWowUm1hR0Q3QlJ4ZGs=
Query string parameters:
action_perform_comment_action:1
This is the button I click on to make the request happen in chrome browser
Button HTML
<button class="yt-uix-button yt-uix-button-size-default yt-uix-button-default yt-uix-button-empty yt-uix-button-has-icon no-icon-markup comment-action-buttons-renderer-thumb yt-uix-sessionlink sprite-comment-actions sprite-like i-a-v-sprite-like" type="button" onclick=";return false;" role="radio" aria-checked="false" aria-label="Like" data-url="/comment_service_ajax?action_perform_comment_action=1" data-sessionlink="itct=COoCEPBbIhMIp8vIp8fg0QIVRtB-Ch2b_QLH" data-action-type="like" data-sessionlink-target="/comment_service_ajax?action_perform_comment_action=1" data-action="CAUQAhojejEzM3YzaG9heXUxZnpxYWkwNGNkbHVpa2xpNXh2b2J1YmcqC29VNlVmTEd0TnVJMAA4AEoVMTE1MDUyMzM1OTE1MzQ4Nzg0MDM5UAA%3D"></button>
This is what I’ve tired
#starts a sesh
with requests.Session() as s:
#Goes to login page
soup = BeautifulSoup(s.get(post).text, "html.parser")
#selects login form
for inp in soup.select("#gaia_loginform input[name]"):
if inp["name"] not in form_data:
form_data[inp["name"]] = inp["value"]
#sends POST request to login
s.post(post, form_data)
ReuestURL3 = 'https://www.youtube.com/comment_service_ajax?action_perform_comment_action=1'
some33 = {'action':'CAUQAhohejEzeWpwa3pqbDJpaXRhZW0yM2VjejBodXRhcWZodnRnKgtVcnNVdVZBSmg1VTAAOABKFTEwNDcyMDg1NDE0MTM2MDE2ODY1NlAA','vote_status':'INDIFFERENT','session_token':'QUFFLUhqbVJCQXVveDdESTZfY2ROTTJWaEJLYkR4NzBUUXxBQ3Jtc0treDFSQTNVbEFhdjdpXzM3T1FaMUw1cnMxZWdUOEhVNUNYNGtfWnZqR29nMlE0NkJzejRudm51Nkx3cGgzUHZHQ0lYRF9hanhnT2JDdUlSRVVKa0hmLVRoNkE4YTJ0RXZ6Q3hSY0hJeU9nbWRqcUVwRzcyamVWN1E1Y19zaUlULU5jajRrZmEzVWs4ZmZVSEc1R3dSQXA5VDJiUDdxTkRzRFBUY3ZMX0dZZXNDbEdNRUE='}
headers3 = {"user-agent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.13+ (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2"}
reas = s.post(ReuestURL3, params=some33,headers=headers3,auth=HTTPBasicAuth('example@gmail.com', 'pass'))
but I still get a 401 error… what’s going wrong why is the request failing?