Skip to content
This repository has been archived by the owner on Jan 22, 2022. It is now read-only.

Webclient requires additional steps to log in from new ip #475

Open
JakedUp opened this issue Jul 19, 2016 · 5 comments
Open

Webclient requires additional steps to log in from new ip #475

JakedUp opened this issue Jul 19, 2016 · 5 comments

Comments

@JakedUp
Copy link

JakedUp commented Jul 19, 2016

The docs state "Users who don’t use two-factor auth will likely need to enable less secure login. If this is needed, a warning will be logged during login (which will print to stderr in the default logging configuration)."

However, I cannot get login to work. I've tried with 2-step & app-specific passwords, and I've tried without 2-step & less secure login enabled. Either way, when I login, it always returns false. When looking at the log file, I see the following entry: "gmusicapi.Webclient3 (webclient:61) [INFO]: failed to authenticate". Mobileclient and Musicmanager login just fine.

I know it's suggested to not use the Webclient, but as far as I can tell, it's the only way I can get my cover art uploaded correctly (Webclient.upload_album_art). When uploading music via Musicmanager, my cover art is removed from the MP3.

Is Webclient login no longer working?

@JakedUp
Copy link
Author

JakedUp commented Jul 19, 2016

Got it! Started running session.py line-by-line over SSH, and found that after submitting the password, there was a third screen where it was asking me to do one of 4 things:

  • Get a text message with a verification code at (•••) •••-••99
  • Get a phone call with a verification code at (•••) •••-••99
  • Confirm the recovery phone you added to this account
  • Confirm the recovery email you added to this account

I simulated submitting one of these steps over SSH, and then Webclient.login worked perfectly.

        form_candidates = response.soup.select("form")
        form = form_candidates[3]
        response = browser.submit(form, 'https://accounts.google.com/ServiceLoginAuth')
        form_candidates = response.soup.select("form")
        form = form_candidates[0]
        form.select('[name=email]')[0]['value'] = 'xxx@gmail.com'
        response = browser.submit(form, 'https://accounts.google.com/ServiceLoginAuth')

I suspect I needed to do this step since I'm running gmusicapi off of a remote webserver, and therefore Google was trying to block the login since it didn't appear to be a known IP address. This is just a theory, but it makes sense.

Wonder if this flow could somehow be integrated into the Webclient login?

@simon-weber
Copy link
Owner

Ah. Yeah, we've had trouble with webclient auth on remote machines: I actually turned off webclient testing from travis because of it.

I don't think there's an easy solution. The webclient just wasn't built for programmatic auth.

@JakedUp
Copy link
Author

JakedUp commented Jul 19, 2016

It's all good. Now that I've successfully logged in with the work-around above, that IP address is now known to Google, and I am longer having login issues. Hopefully this thread helps someone else who is having the same issue. You should probably also look into putting a notice in the docs about remote connections not working. I could not find a single thread of information about this anywhere.

@simon-weber simon-weber changed the title Webclient not logging in using less secure login Webclient requires additional steps to log in from new ip Jul 19, 2016
@askvictor
Copy link

I had some problems with using a TFA account with WebClient - it won't accept an app-specific password, but it's not possible to use less-secure login with TFA. I added the following lines in session.py after submitting the password. I also had to change the login method in WebClient to accept kwargs so as to be able to pass the TFA token across; now I can log in using something like wc.login("email", "password", totp="TFATokenFromAuthenticator")

        if 'totp' in kwargs:  # Using 2FA
            form_candidates = response.soup.select("form")

            #commented out as there is another form to try a different option
            # if len(form_candidates) > 1:
            #     log.error("Google login form dom has changed; there are %s candidate forms:\n%s",
            #               len(form_candidates), form_candidates)
            #     return False

            form = form_candidates[0]
            form.select("#totpPin")[0]['value'] = kwargs["totp"]

            response = browser.submit(form, 'https://accounts.google.com/signin/challenge/totp/2')

            try:
                response.raise_for_status()
            except requests.HTTPError:
                log.exception("submitting OTP form failed")
                return False

@sashgorokhov
Copy link

Had the same issue. Just False login status, same messages in logs. Added application password in google and used it instead of mine. worked.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants