使用无头Chrome/Puppeteer登录Google时出现问题

4
我正在尝试自动化某些工作任务。我们有一个需要通过Google登录的门户网站。我创建了一个 Puppeteer 实例,导航到 Google 认证页面,输入我的电子邮件和密码,然后存储 cookie,以便我可以浏览并操作门户网站。
这在我的本地环境中完美地运行,但我已将其部署到 Heroku 并且 Google 添加了一个登录挑战。在输入密码后,我会收到“验证您的身份”页面,上面写着“此设备未被识别”,并要求我完成 2-FA 认证。
我知道我无法关闭 2-FA,那么绕过此问题的最佳方法是什么?
或者,是否有更简单的方法登录由 Google 认证保护的网站并存储会话 cookie?
以下是我的 Puppeteer 代码,非常感谢任何帮助:
async function getCookies() {
    const browser = await puppeteer.launch({ 
      args: [
        '--no-sandbox', 
        '--disable-setuid-sandbox', 
        '--disable-gpu'
      ] 
    })
    const page = await browser.newPage()
    await page.setUserAgent('Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36')
    await page.goto(process.env.URL)
    await page.waitForSelector('#identifierId')
    await page.type('#identifierId', process.env.EMAIL, { delay: 5 })
    await page.click('#identifierNext')
    await page.waitForSelector('#password input[type="password"]', { visible: true });
    await page.type('#password input[type="password"]', process.env.PASS, { delay: 5 })
    await page.click('#passwordNext')
    await page.waitFor(3000)
    const cookies = await page.cookies()
    await browser.close()
    return cookies
  }

你找到解决方法了吗? - id3vz
4个回答

1
很抱歉,这是不可能的,也不是你想要的答案。
我知道我不能关闭双重认证,那么绕过它的最佳方法是什么?
如果可以绕过它,那么黑客就会打开大门,因为双重认证作为流程中的额外步骤,第二个安全层将重新确认您的身份。它的目的是使攻击者的生活更加困难,并减少欺诈风险!

0

我也会在其中添加一个Android应用程序。您可以使用短信代码设置2FA,具有SMS读取权限的Android应用程序可以读取短信并连接到后端。

后端可以发送推送消息,可能使用Firebase Cloud Messaging将其输入到运行headless Chrome的本地Node.js实例中,以输入到2FA屏幕中。

我认为没有其他方法可以做到这一点。虽然我建议不要这样做,因为它可能会为安全问题打开一些后门。


0

实际上,您可以使用Puppeteer中的Twilio API来编程接收短信验证码。您需要为此设置一个特殊的Google帐户,并将Twilio号码作为移动电话使用,或者更改当前Google帐户的主要移动电话号码以适用于Twilio号码,并在Google帐户信息中使用常规号码作为辅助联系方式。


这似乎只能在美国、加拿大和英国以外的地方使用。在这些列出的国家,Twilio号码将无法从短代码接收短信。请参见此处 - jeff

0

我的工作解决方案(需要一些重构)

const puppeteer = require('puppeteer');
(async () => {
  const browser = await puppeteer.launch({
    headless: false,        // for debugging only
    ignoreHTTPSErrors: true // This happens when you use a self signed certificate locally
  })
  const page = await browser.newPage()

  await page.setViewport({ width: 1280, height: 800 })
  await page.goto('https://myawesomesystem/loginFrm01')
  const navigationPromise = page.waitForNavigation()

  // Clicks on the login button    
  const googleLoginButtonSelector = 'body > section > ... > div'
  await page.waitForSelector( googleLoginButtonSelector )
  await page.click( googleLoginButtonSelector )

  // wait for the google oauth page to open
  const googleOAuthTarget = await browser.waitForTarget( target => {
    // console.log( target.url() ); // debugging
    return target.url().indexOf('https://accounts.google.com/signin/oauth/identifier') !== -1
  })

  const googleOAuthPage = await googleOAuthTarget.page()

  await googleOAuthPage.waitForSelector('#identifierId')
  await googleOAuthPage.type('#identifierId', CRED.user, { delay: 5 } )
  await googleOAuthPage.click('#identifierNext')

  await googleOAuthPage.waitForSelector('input[type="password"]', { visible: true })
  await googleOAuthPage.type('input[type="password"]', CRED.pass )

  await googleOAuthPage.waitForSelector('#passwordNext', { visible: true })
  await googleOAuthPage.click('#passwordNext')

  await navigationPromise

  // HERE:
  // the user has been authenticated
  // or login window was closed
  // or whatever else, please check

  await browser.close()
})()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接