'Python Login to UPS.com returns 403

I had a script that would login to my UPS.com account to receive all incoming packages. The following code was working for a while but not anymore:

import requests
from bs4 import BeautifulSoup

s = requests.Session()
url = "https://www.ups.com/lasso/login?loc=en_US&returnto=https%3A%2F%2Fwww.ups.com%2Fus%2Fen%2FHome.page"
headers = {
  'Connection': 'keep-alive',
  'Pragma': 'no-cache',
  'Cache-Control': 'no-cache',
  'Upgrade-Insecure-Requests': '1',
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',
  'Sec-Fetch-Dest': 'document',
  'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
  'Sec-Fetch-Site': 'same-origin',
  'Sec-Fetch-Mode': 'navigate',
  'Sec-Fetch-User': '?1',
  'Referer': 'https://www.ups.com/us/en/services/tracking/mychoice.page',
  'Accept-Language': 'en-US,en;q=0.9',
}
response = s.get(url, headers=headers, data = payload)
soup = BeautifulSoup(response.content, 'html.parser')
# Get CSRF Token
token = soup.find(id='CSRFToken').get('value')

# Now login
url = "https://www.ups.com/lasso/login"

payload = "CSRFToken={}&loc=null&returnto=https%253A%252F%252Fwww.ups.com%252Fupsmychoice%253Floc%253Den_US&forgotpassword=YZ&connectWithSocial=YZ&userID=MYUSERNAME&password=MYPASSWORD&rememberMe=1&getTokenWithPassword=&ioBlackBox=&ioElapsedTime=5026".format(token)
headers = {
  'Connection': 'keep-alive',
  'Pragma': 'no-cache',
  'Cache-Control': 'no-cache',
  'Origin': 'https://www.ups.com',
  'Upgrade-Insecure-Requests': '1',
  'Content-Type': 'application/x-www-form-urlencoded',
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36',
  'Sec-Fetch-Dest': 'document',
  'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
  'Sec-Fetch-Site': 'same-origin',
  'Sec-Fetch-Mode': 'navigate',
  'Sec-Fetch-User': '?1',
  'Referer': 'https://www.ups.com/lasso/login?loc=en_US&returnto=https%3A%2F%2Fwww.ups.com%2Fus%2Fen%2Fservices%2Ftracking%2Fmychoice.page',
  'Accept-Language': 'en-US,en;q=0.9',
  'Content-Type': 'application/x-www-form-urlencoded',
}

response = s.post(url, headers=headers, data = payload)

This now returns a 403 with message "You don't have permission to access ... on this server"

I used Selenium webdriver on the same server to login and this worked when I filled out the form information with my credentials. However I am looking for a solution that only uses requests module.

I have even tried copying the login request directly to Postman and I received the same 403 (even when I manually updated CSRFToken)

What can I do to login via requests to ups.com?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source