Fetching latest headlines…
[BA-007] Logins, sessions and authentication in browser automation
NORTH AMERICA
πŸ‡ΊπŸ‡Έ United Statesβ€’July 6, 2026

[BA-007] Logins, sessions and authentication in browser automation

0 views0 likes0 comments
Originally published byDev.to

Many automation tasks require being logged in. The naive approach is to fill the login form every time, but that is slow and breaks if the page changes.

Playwright lets you save and restore browser sessions using storage_state:

from playwright.sync_api import sync_playwright

def save_session(url: str, username: str, password: str, save_path: str):
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        page.goto(url)

        page.fill("#username", username)
        page.fill("#password", password)
        page.click("#login-button")

        page.wait_for_url("**/dashboard")

        context = browser.contexts[0]
        context.storage_state(path=save_path)
        print(f"Session saved to {save_path}")

        browser.close()

save_session(
    "https://example.com/login",
    "your-username",
    "your-password",
    "session.json"
)

Once you have the session file, you can reuse it without logging in again:

from playwright.sync_api import sync_playwright

def load_session(start_url: str, session_path: str):
    with sync_playwright() as p:
        context = p.chromium.launch_persistent_context(
            user_data_dir="./profile",
            storage_state=session_path
        )
        page = context.new_page()
        page.goto(start_url)

        if "login" not in page.url:
            print("Session restored, already logged in")
        else:
            print("Session expired, need to login again")

        browser = context.browser
        browser.close()

The storage_state file contains cookies and localStorage data. It works across browser launches.

For sites with 2FA, automate the login once manually and save the session. Then reuse it for all subsequent runs:

def login_with_2fa_once(save_path: str):
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        page.goto("https://github.com/login")

        page.fill("#login_field", "your-email")
        page.fill("#password", "your-password")
        page.click("[name=commit]")

        input("Enter the 2FA code and press Enter here after logging in...")

        context = browser.contexts[0]
        context.storage_state(path=save_path)
        print(f"Session with 2FA saved to {save_path}")
        browser.close()

This pauses and waits for you to enter the 2FA code manually. After that the session is saved and can be reused.

You can also handle session expiration by checking the current URL and retrying the login:

def with_session(url: str, session_path: str, login_fn):
    with sync_playwright() as p:
        context = p.chromium.launch_persistent_context(
            user_data_dir="./profile",
            storage_state=session_path
        )
        page = context.new_page()
        page.goto(url)

        if "login" in page.url:
            print("Session expired, logging in again")
            login_fn(page)
            context.storage_state(path=session_path)

        return page

This pattern checks if the page redirected to a login page and refreshes the session automatically.

Using saved sessions turns a multi step login into a one second page load.

That's all for now.
Thanks for reading!

Comments (0)

Sign in to join the discussion

Be the first to comment!