MestreLion / humblebundle

API for managing Humble Bundle games library
GNU General Public License v3.0
211 stars 38 forks source link

authentication fails prior to processlogin #46

Open macfreek opened 6 years ago

macfreek commented 6 years ago

I'm trying to get humblebundle.py to work, but can't get past the first authentication.

        log.info("Authenticating at '%s/processlogin'", self.url)

        try:
            # Could also get the token from res.headers.get("Set-Cookie")
            token = re.search(r"\s+value=['\"]([^'\"]+)['\"]",
                              re.search(r"(<input\s+[^>]*\s+name\s*=\s*"
                                        "['\"]_le_csrf_token['\"][^>]*>)",
                                        res.read()).groups()[0]).groups()[0]
        except Exception as e:
            raise HumbleBundleError("Could not retrieve token: %r", e)

The first error I got was:

('Could not retrieve token: %r', TypeError('cannot use a string pattern on a bytes-like object',))

This was easily fixed by two small fixes:

However, I still got an error:

Could not retrieve token: AttributeError("'NoneType' object has no attribute 'groups'",)

The cause is that r"(<input\s+[^>]*\s+name\s*=\s*['\"]_le_csrf_token['\"][^>]*>)" can't be found in the HTML output of www.humblebundle.com/home/keys.

A quick debug seems to indicate that HTML output is that of the Humble login page (https://www.humblebundle.com/login?goto=%2Fhome%2Fkeys, I expected httpbot or urllib2 handled the redirect), which -with a regular browser- does indeed NOT contain the word "token" nor "csrf", let alone "_le_csrf_token".

Note that I enabled two factor authentication (2FA), not sure if that matters.

Any suggestion to help me debug this is appreciated!

macfreek commented 6 years ago

Perhaps a general suggestion: why not use https://www.humblebundle.com/api/v1/user/order instead of https://www.humblebundle.com/home/keys in update()?

isavegas commented 6 years ago

The 2FA does break the login flow for this application, as it doesn't handle the fact that HumbleBundle requests an authentication code from the user before returning a page that includes the session cookie. Currently, I'm caught up on trying to fix ('Could not retrieve token: %r', TypeError('cannot use a string pattern on a bytes-like object',)), but disabling 2FA might allow you to use the program successfully.

macfreek commented 6 years ago

Thanks for the reply @isavegas. I decided not to use this library, but manually get the session key using the method in this Stack Overflow answer. It's not very pretty, but since I only used it for my own scripts, I'm fine with it.

MestreLion commented 6 years ago

Perhaps a general suggestion: why not use https://www.humblebundle.com/api/v1/user/order instead of https://www.humblebundle.com/home/keys in update()?

... because at the time I started developing this, https://www.humblebundle.com/api/v1/user/order did not exist, or I was not aware of it! Thanks for pointing it out, an API endpoint from HumbleBundle might simplify the code immensely, and maybe help fix many auth-related issues such as #33, #32 and #10. It could also be a new starting point for #47

MestreLion commented 6 years ago

Thanks for the reply @isavegas. I decided not to use this library, but manually get the session key using the method in this Stack Overflow answer. It's not very pretty, but since I only used it for my own scripts, I'm fine with it.

That's exactly what the -A/--auth option is for: a way for you to input a valid _simpleauth_sess cookie value from an authenticated browser, thus bypassing my library's (currently broken) login/auth methods.