Simulating GitHub Login
Login Process Overview
When implementing login simulation for GitHub, three main steps are required:
- Retrieve the authenticity token from the login page using
session.get - Construct form data and headers, then submit to the
/sessionendpoint viasession.post - Verify login status by parsing the profile page title
Main Function Implementation
if __name__ == '__main__':
http_session = requests.session()
http_session.headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36'
}
csrf_token = fetch_csrf_token(http_session)
perform_login(http_session)
verify_login(http_session)
Retrieving the CSRF Token
The authenticity token is embedded in the GitHub login page HTML. Extract it using a regex pattern:
def fetch_csrf_token(http_session: Session) -> str:
"""
Fetch the CSRF token from the GitHub login page.
"""
response = http_session.get('https://github.com/login')
if response.status_code != 200:
raise ConnectionError("Failed to load login page")
html_content = response.content.decode()
csrf_token = re.findall(r'name="authenticity_token" value="(.*?)"', html_content)[0]
return csrf_token
Submitting Login Request
def perform_login(http_session: Session, token: str, username: str, password: str):
"""
Submit login credentials to the /session endpoint.
"""
login_payload = {
"commit": "Sign in",
"authenticity_token": token,
"login": username,
"password": password,
"webauthn-conditional": "undefined",
"javascript-support": "true",
"webauthn-support": "supported",
"webauthn-iuvpaa-support": "supported",
"return_to": "https://github.com/login"
}
response = http_session.post(url='https://github.com/session', data=login_payload)
if response.status_code != 200:
raise ConnectionError("Login request failed")
return response
Verifying Login Status
Login success can be verified by checking the profile page title. GitHub shows the username in the title when not logged in, but only shows content when authenticated:
def verify_login(http_session: Session, username: str):
"""
Verify login by checking the profile page title.
"""
response = http_session.get(f'https://github.com/{username}')
html = response.content.decode('utf-8')
title_pattern = re.findall(r'<title>(.+?)(GitHub)?</title>', html)
try:
suffix = title_pattern[0][1]
except IndexError:
suffix = ""
if suffix == "":
print("Login successful")
else:
print("Login failed")
with open("profile.html", "wb") as file:
file.write(response.content)
Implementation Notes
The requests.Session object maintains cookies across requests, which is essential for session-based authentication. The CSRF token prevents cross-site request forgery attacks and must be included in the login POST request. The token is obtained by parsing the hidden input field in the login page HTML.