playwright-community / playwright-go

Playwright for Go a browser automation library to control Chromium, Firefox and WebKit with a single API.
https://playwright-community.github.io/playwright-go/
MIT License
1.94k stars 145 forks source link

Suggestion:Example for how to do a POST manually #349

Open mackaybe opened 1 year ago

mackaybe commented 1 year ago
func getJWT(samlUrl string, samlResp string) (jwt JWT, err error) {
    err = playwright.Install()
    if err != nil {
        log.Fatalf("Could not install playwright deps: %v", err)
    }
    pw, err := playwright.Run()
    if err != nil {
        log.Fatal(err)
    }
    defer pw.Stop()
    browser, err := pw.Chromium.Launch()
    if err != nil {
        log.Fatalf("Could not launch browser: %v\n", err)
    }
    page, err := browser.NewPage()
    if err != nil {
        log.Fatalf("Could not create page: %v\n", err)
    }
    defer browser.Close()
    headers := make(map[string]string)
    headers["origin"] = "https://portal.example.com"
    headers["referer"] = "https://portal.example.com/"
    headers["Content-Type"] = "application/x-www-form-urlencoded"
    formData := url.Values{}
    formData.Add("RelayState", "/portal")
    formData.Add("SAMLResponse", samlResp)
    handler := func(route playwright.Route, request playwright.Request) {
        if request.Method() == "GET" {
            postMethod := "POST"
            route.Continue(playwright.RouteContinueOptions{
                Headers:  headers,
                Method:   &postMethod,
                PostData: []byte(formData.Encode()),
            })
        } else {
            // If the request is not a POST request, abort it
            if err := route.Abort(); err != nil {
                log.Fatalf("Failed to abort the request: %v", err)
            }
        }
    }
    err = page.Route(samlUrl, handler)
    if _, err = page.Goto(samlUrl); err != nil {
        log.Fatalf("Could not goto callback URL: %v\n", err)
    }
    parsedUrl, err := url.Parse(samlUrl)
    if err != nil {
        log.Fatalf("Could not parse saml url: %v\n", err)
    }
    appOrigin := parsedUrl.Scheme + "://" + parsedUrl.Host
    storage, err := page.Context().StorageState()
    if err != nil {
        log.Fatalf("Could not retrieve localStorage from browser: %v\n", err)
    }
    var tokenString string
    for _, aurigin := range storage.Origins {
        if aurigin.Origin == appOrigin {
            for _, entry := range aurigin.LocalStorage {
                if entry.Name == "access_token" {
                    tokenString = entry.Value
                }
            }
        }
    }
    json.Unmarshal([]byte(tokenString), &jwt)
    return jwt, nil
}