I am using MechanicalSoup to login to a website via Python 3.6 and I'm having issues with the CSRF token.
Every time i request the html back i read "Invalid CSRF token: Forbidden". Searching the html on the login page, the closest match for a element id that looks like the token is "autheticity_token" which appears to be already filled in with the token.
I was able to use "re" module to extract the token and resubmit it to the element with the id i talked about above but no luck. Note, i had to find the element by id since a name is not provided for it (this is why my Robobrowser way of doing it didn't work).
This is the element that I think corresponds to the CSRF:
<input id="authenticity_token" type="hidden" value="b+csp/9zR/a1yfuPPIYJSiR0v8jJUTaJaGqJmJPmLmivSn4GtLgvek0nyPvcJ0aOgeo0coHpl94MuH/r1OK5UA==">
I would extract, in this case "b+csp/9zR/a1yfuPPIYJSiR0v8jJUTaJaGqJmJPmLmivSn4GtLgvek0nyPvcJ0aOgeo0coHpl94MuH/r1OK5UA==" and resubmit it to that element
Here is my code with dummy values for user,pass, and url
import mechanicalsoup
import re
def return_token(str1):
match1 = "authenticity_token"
match2 = ".*value\=\"(.*)\".*"
for x in range(len(str1)):
line = str1[x]
if re.findall(match1,line):
token = re.findall(match2,line)[0]
return token
url1 = ""
username = ""
password = ""
browser = mechanicalsoup.Browser()
page = browser.get(url1)
str0 = page.text
token = return_token(str0.split('\n'))
#print(str0)
form = page.soup.find("form",{"id":"loginForm"})
form.find('input', {'name': 'username'})['value'] = username
form.find('input', {'name': 'password'})['value'] = password
form.find('input', {'id': 'authenticity_token'})['value'] = str(token)
response = browser.submit(form, page.url)
print(response.text)