Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

navigation failed: net::ERR_INVALID_AUTH_CREDENTIALS #994

Open
wAnFen1017 opened this issue Dec 27, 2023 · 11 comments
Open

navigation failed: net::ERR_INVALID_AUTH_CREDENTIALS #994

wAnFen1017 opened this issue Dec 27, 2023 · 11 comments
Labels
question Questions related to rod

Comments

@wAnFen1017
Copy link

wAnFen1017 commented Dec 27, 2023

Rod Version: v0.114.5

我有一个隧道代理服务,支持http和https。他需要通过 http://user:pwd@ip:port 的形式通过验证,该服务测试过没有问题。

参照文档中 go browser.MustHandleAuth(user, pwd)() 成功设置了代理,并打开网站验证无误。但是同样的逻辑放在浏览器池browsePool中则报错,在创建browserPool之前设置browser.MustHandleAuth会报错 navigation failed: net::ERR_INVALID_AUTH_CREDENTIALS;创建后设置browser.MustHandleAuth则会报错 panic: {-32000 Invalid state for continueInterceptedRequest }。以下是我的代码

// Package main
// @Time      : 2023-12-06 09:47
// @Author    : wAnFen
// @File      : render.go
// @Go        : 1.21.3

package main

import (
	"github.com/go-rod/rod"
	"github.com/go-rod/rod/lib/launcher"
	"github.com/go-rod/rod/lib/proto"
	"log"
	"sync"
)

func RunRod(url string) {
	var rodUrl string
	l := launcher.New().
		Headless(false).
		Leakless(true).
		NoSandbox(true).
		Delete("enable-automation").
		Set("ignore-certificate-errors").
		Set("ignore-certificate-errors-spki-list").
		Set("ignore-ssl-errors").
		Set("disable-blink-features", "AutomationControlled").
		Set("disable-setuid-sandbox").
		Set("disable-gpu").
		Set("disable-dev-shm-usage").
		Set("unlimited-storage").
		Set("disable-accelerated-2d-canvas").
		Set("full-memory-crash-report")

	l = l.Proxy("127.0.0.1:6501")

	path, has := launcher.LookPath()
	if has == true {
		rodUrl = l.Bin(path).MustLaunch()
	} else {
		rodUrl = l.MustLaunch()
	}

	log.Println("StartURL : ", rodUrl)
	browser := rod.New().ControlURL(rodUrl).MustConnect()

	browser.MustIgnoreCertErrors(true)

	user := "user"
	pwd := "password"

	go browser.MustHandleAuth(user, pwd)()

	browsePool := rod.NewBrowserPool(20)
	create := func() *rod.Browser {
		//go browser.MustHandleAuth(user, pwd)()
		return browser.MustIncognito()
	}

	// 单一线程正常运行
	//b := browsePool.Get(create)
	//page, err := b.Page(proto.TargetCreateTarget{URL: url})
	//if err != nil {
	//	log.Println("browser.Page Err : ", err)
	//}
	//println(page.MustElement("html").MustText())

	// 在goroutine中运行报错 navigation failed: net::ERR_INVALID_AUTH_CREDENTIALS
	var wg sync.WaitGroup
	for i := 0; i <= 3; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			b := browsePool.Get(create)
			page, err := b.Page(proto.TargetCreateTarget{URL: url})
			if err != nil {
				log.Println("browser.Page Err : ", err)
			}
			println(page.MustElement("html").MustText())
		}()
	}
	wg.Wait()
}

func main() {
	RunRod("http://api.ipify.org")
}

@wAnFen1017 wAnFen1017 added the question Questions related to rod label Dec 27, 2023
Copy link

Please fix the format of your markdown:

7 MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]

generated by check-issue

@ysmood
Copy link
Collaborator

ysmood commented Dec 27, 2023

用法的问题,create 里处理 auth

@wAnFen1017
Copy link
Author

用法的问题,create 里处理 auth

如果改成在create中处理时则会报 panic: {-32000 Invalid state for continueInterceptedRequest }

create := func() *rod.Browser {
		go browser.MustHandleAuth(user, pwd)()
		return browser.MustIncognito()
	}

@ysmood
Copy link
Collaborator

ysmood commented Dec 27, 2023

如果在外围处理,需要处理每个 auth 事件,browser.MustHandleAuth 只处理碰到的第一个,你看看它的源代码就懂了

@wAnFen1017
Copy link
Author

wAnFen1017 commented Dec 27, 2023

如果在外围处理,需要处理每个 auth 事件,browser.MustHandleAuth 只处理碰到的第一个,你看看它的源代码就懂了

我在每个goroutine中做处理不可实现吗,或者如果在外围统一处理的话,我查到是使用EachEvent去控制全部活动,我改成这样,依旧报错 panic: {-32000 Invalid state for continueInterceptedRequest }

	go browser.EachEvent(func(e *proto.FetchAuthRequired) {
		fakeAuth := &proto.FetchAuthChallengeResponse{
			Response: proto.FetchAuthChallengeResponseResponseProvideCredentials,
			Username: user,
			Password: pwd,
		}
		err := proto.FetchContinueWithAuth{
			RequestID:             e.RequestID,
			AuthChallengeResponse: fakeAuth,
		}.Call(browser)
		if err!=nil{
			panic(err)
		}
	}, func(e *proto.FetchRequestPaused) {
		err := proto.FetchContinueRequest{
			RequestID: e.RequestID,
		}.Call(browser)
		if err!=nil{
			panic(err)
		}
	})()

	browsePool := rod.NewBrowserPool(20)
	create := func() *rod.Browser {
		return browser.MustIncognito()
	}
        // browser.MustPage()

@ysmood
Copy link
Collaborator

ysmood commented Dec 27, 2023

那你可能需要自己 debug 一下,应该是用法的问题,这方面 chromium cdp 缺少文档说明,只能猜测用法,让我来和让你来是一样的。

你这里报错的意思是 FetchContinueRequest 用法错误

@wAnFen1017
Copy link
Author

我看了您另外的一个回答 #654 ,我感觉我和他的问题应该是差不多的,但是我这里使用了BrowserPool,所以我猜测是不是BrowserPool的问题,以下是我的完整代码,此时报错信息是 navigation failed: net::ERR_INVALID_AUTH_CREDENTIALS

// Package main
// @Time      : 2023-12-06 09:47
// @Author    : wAnFen
// @File      : render.go
// @Go        : 1.21.3

package main

import (
	"github.com/go-rod/rod"
	"github.com/go-rod/rod/lib/launcher"
	"github.com/go-rod/rod/lib/proto"
	"log"
	"sync"
)

func RunRod(url string) {
	var rodUrl string
	l := launcher.New().
		Headless(false).
		Leakless(true).
		NoSandbox(true).
		Delete("enable-automation").
		Set("ignore-certificate-errors").
		Set("ignore-certificate-errors-spki-list").
		Set("ignore-ssl-errors").
		Set("disable-blink-features", "AutomationControlled").
		Set("disable-setuid-sandbox").
		Set("disable-gpu").
		Set("disable-dev-shm-usage").
		Set("unlimited-storage").
		Set("disable-accelerated-2d-canvas").
		Set("full-memory-crash-report")

	l = l.Proxy("http://127.0.0.1:6501")

	path, has := launcher.LookPath()
	if has == true {
		rodUrl = l.Bin(path).MustLaunch()
	} else {
		rodUrl = l.MustLaunch()
	}

	log.Println("StartURL : ", rodUrl)
	browser := rod.New().ControlURL(rodUrl).MustConnect()

	browser.MustIgnoreCertErrors(true)

	user := "user"
	pwd := "pwd"

	go browser.EachEvent(func(e *proto.FetchAuthRequired) {
		fakeAuth := &proto.FetchAuthChallengeResponse{
			Response: proto.FetchAuthChallengeResponseResponseProvideCredentials,
			Username: user,
			Password: pwd,
		}
		err := proto.FetchContinueWithAuth{
			RequestID:             e.RequestID,
			AuthChallengeResponse: fakeAuth,
		}.Call(browser)
		if err != nil {
			panic(err)
		}
	}, func(e *proto.FetchRequestPaused) {
		err := proto.FetchContinueRequest{
			RequestID: e.RequestID,
		}.Call(browser)
		if err != nil {
			panic(err)
		}
	})()

	browsePool := rod.NewBrowserPool(20)
	create := func() *rod.Browser {
		return browser.MustIncognito()
	}

	var wg sync.WaitGroup
	for i := 0; i <= 3; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			b := browsePool.Get(create)
			page, err := b.Page(proto.TargetCreateTarget{URL: url})
			if err != nil {
				log.Println("browser.Page Err : ", err)
			}
			println(page.MustElement("html").MustText())
		}()
	}
	wg.Wait()
}

func main() {
	RunRod("http://api.ipify.org")
}

@lc
Copy link

lc commented Feb 20, 2024

I'm encountering this issue as well. Not sure what I'm doing wrong here.

I have a proxy that doesn't return HTTP/1.1 407 Proxy Authentication Required and still passes through. However, my proxy provider allows sticky-sessions when a username:pass is sent.

What would be the correct pattern? I know it's not proto.FetchAuthRequired, but I am struggling to find such a use-case in the docs. I tried using HijackRouter and setting the Proxy-Authorization header for the request, but that forwards the header to the fetched URL rather than for the proxy connection.

This code does not work:

	go browser.EachEvent(func(e *proto.FetchAuthRequired) {
		fakeAuth := &proto.FetchAuthChallengeResponse{
			Response: proto.FetchAuthChallengeResponseResponseProvideCredentials,
			Username: "user",
			Password: "pass",
		}
		err := proto.FetchContinueWithAuth{
			RequestID:             e.RequestID,
			AuthChallengeResponse: fakeAuth,
		}.Call(browser)
		if err != nil {
			panic(err)
		}
	}, func(e *proto.FetchRequestPaused) {
		err := proto.FetchContinueRequest{
			RequestID: e.RequestID,
		}.Call(browser)
		if err != nil {
			panic(err)
		}
	})()

@xujinzheng
Copy link
Contributor

following code is worked

  1. create page
  2. auth handle
browser.Page(proto.TargetCreateTarget{})
go browser.MustHandleAuth(username, password)()

@lc
Copy link

lc commented Mar 18, 2024

Switched my proxy provider and it worked.

@wAnFen1017
Copy link
Author

following code is worked

  1. create page
  2. auth handle
browser.Page(proto.TargetCreateTarget{})
go browser.MustHandleAuth(username, password)()

Thank you for your answer. This is indeed effective under normal requests, but it does not work in browser pools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Questions related to rod
Projects
None yet
Development

No branches or pull requests

4 participants