简体   繁体   English

使用 Headless Chrome / Puppeteer 无法登录 Google

[英]Trouble Logging In To Google with Headless Chrome / Puppeteer

I'm trying to automate certain tasks for work.我正在尝试自动化某些工作任务。 We have a portal that requires you to sign in through Google.我们有一个要求您通过 Google 登录的门户。 I've created a Puppeteer instance that navigates to the Google auth page, types in my email and password, then stores the cookies so I can navigate through and manipulate the portal.我创建了一个 Puppeteer 实例,它导航到 Google 身份验证页面,输入我的电子邮件和密码,然后存储 cookie,以便我可以浏览和操作门户。

This works perfectly on my local environment, but I've deployed it to Heroku and Google adds a sign in challenge.这在我的本地环境中完美运行,但我已将其部署到 Heroku 并且 Google 添加了登录挑战。 After entering the password, I'm given the 'Verify it's you' page that says 'This device isn't recognized' and asks me to complete 2-FA auth.输入密码后,我会看到“验证是您身份”页面,显示“无法识别此设备”并要求我完成 2-FA 身份验证。

I know I can't turn off 2-FA, so what would be the best way to bypass this?我知道我无法关闭 2-FA,那么绕过它的最佳方法是什么?

Alternatively, is there an easier way to log in to a website guarded by Google auth and store the session cookies?或者,是否有更简单的方法来登录由 Google 身份验证保护的网站并存储会话 cookie?

Here's my puppeteer code, any help would be much appreciated:这是我的 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
  }

Not possible I am afraid and not the answer you want.不可能恐怕,而不是你想要的答案。

I know I can't turn off 2-FA, so what would be the best way to bypass this?`我知道我无法关闭 2-FA,那么绕过它的最佳方法是什么?`

If it was possible to bypass then it kinda opens the door for hackers as Two-factor authentication works as an extra step in the process, a second security layer, that will reconfirm your identity.如果可以绕过,那么它有点为黑客打开了大门,因为双因素身份验证是该过程中的一个额外步骤,即第二个安全层,它将重新确认您的身份。 Its purpose is to make attackers' life harder and reduce fraud risks!其目的是让攻击者的生活更加艰难并降低欺诈风险!

I would have added an Android app in the mix too.我也会在组合中添加一个 Android 应用程序。 You can set up the 2FA with SMS codes and an Android app with SMS read permission can read the SMS and connect with a backend.您可以使用 SMS 代码设置 2FA,并且具有 SMS 读取权限的 Android 应用程序可以读取 SMS 并与后端连接。

The backend can send push message, probably using Firebase Cloud Messaging to the local Node.js instance where the headless Chrome is running to input it in the 2FA screen.后端可以发送推送消息,可能使用 Firebase 云消息传递到运行无头 Chrome 的本地 Node.js 实例,以将其输入到 2FA 屏幕中。

I don't think there's any other way to do it.我认为没有其他方法可以做到这一点。 Although I would recommend not doing it, since it may open some backdoor for security issues.虽然我不建议这样做,因为它可能会为安全问题打开一些后门。

I is actually possible using Twilio API within Puppeteer to programatically receive the SMS code.我实际上可以在 Puppeteer 中使用 Twilio API 以编程方式接收 SMS 代码。 You will have to setup a special Google account for this to work with the Twilio number as mobile phone OR change your current Google account primary mobile number for the Twilio number, and use your regular number as a secondary contact in your Google account info.您必须为此设置一个特殊的 Google 帐户才能将 Twilio 号码用作手机,或者将您当前的 Google 帐户主要手机号码更改为 Twilio 号码,并在您的 Google 帐户信息中使用您的常规号码作为辅助联系人。

My working solution (needs some refactoring)我的工作解决方案(需要一些重构)

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()
})()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM