Git Product home page Git Product logo

Comments (8)

mkb79 avatar mkb79 commented on May 23, 2024

For documenting purposes only

To use the auth code flow, simply replace the function
audible.login.build_oauth_url with these code:

def build_oauth_url(
    country_code: str,
    domain: str,
    market_place_id: str,
    code_challenge,
    serial: Optional[str] = None,
    with_username=False
) -> Tuple[str, str]:
    """Builds the url to login to Amazon as an Audible device"""
    if with_username and domain.lower() not in ("de", "com", "co.uk"):
        raise ValueError("Login with username is only supported for DE, US "
                         "and UK marketplaces!")
        
    serial = serial or build_device_serial()
    client_id = build_client_id(serial)

    if with_username:
        base_url = f"https://www.audible.{domain}/ap/signin"
        return_to = f"https://www.audible.{domain}/ap/maplanding"
        assoc_handle = f"amzn_audible_ios_lap_{country_code}"
        page_id = "amzn_audible_ios_privatepool"
    else:
        base_url = f"https://www.amazon.{domain}/ap/signin"
        return_to = f"https://www.amazon.{domain}/ap/maplanding"
        assoc_handle = f"amzn_audible_ios_{country_code}"
        page_id = "amzn_audible_ios"

    oauth_params = {
        "openid.oa2.response_type": "code",
        "openid.oa2.code_challenge_method": "S256",
        "openid.oa2.code_challenge": code_challenge
        "openid.return_to": return_to,
        "openid.assoc_handle": assoc_handle,
        "openid.identity": "http://specs.openid.net/auth/2.0/"
                           "identifier_select",
        "pageId": page_id,
        "accountStatusPolicy": "P1",
        "openid.claimed_id": "http://specs.openid.net/auth/2.0/"
                             "identifier_select",
        "openid.mode": "checkid_setup",
        "openid.ns.oa2": "http://www.amazon.com/ap/ext/oauth/2",
        "openid.oa2.client_id": f"device:{client_id}",
        "openid.ns.pape": "http://specs.openid.net/extensions/pape/1.0",
        "marketPlaceId": market_place_id,
        "openid.oa2.scope": "device_auth_access",
        "forceMobileLayout": "true",
        "openid.ns": "http://specs.openid.net/auth/2.0",
        "openid.pape.max_auth_age": "0"
    }

    return f"{base_url}?{urlencode(oauth_params)}", serial

The code_challenge are created from a code_verifier.
A app must rember the code_verifier to register a device
later.

The code_verifier and code_challenge can be created with these functions:

def create_code_verifier(length: int = 32) -> bytes:
    verifier = secrets.token_bytes(length)
    return base64.urlsafe_b64encode(verifier).rstrip(b'=')

def create_s256_code_challenge(verifier: bytes):
    m = hashlib.sha256(verifier)
    return base64.urlsafe_b64encode(m.digest()).rstrip(b'=')

A successful authorization returns a url with a openid.oa2.authorization_code query
param instead of openid.oa2.access_token.

With the authorization_code and the code_verifier a new device
can be registrated. Simply change the body variable of the
function audible.register.register to:

body = {
    "requested_token_type":
        ["bearer", "mac_dms", "website_cookies",
         "store_authentication_cookie"],
    "cookies": {
        "website_cookies": [],
        "domain": f".amazon.{domain}"},
    "registration_data": {
        "domain": "Device",
        "app_version": "3.26.1",
        "device_serial": serial,
        "device_type": "A2CZJZGLK2JJVM",
        "device_name": (
            "%FIRST_NAME%%FIRST_NAME_POSSESSIVE_STRING%%DUPE_"
            "STRATEGY_1ST%Audible for iPhone"),
        "os_version": "13.5.1",
        "device_model": "iPhone",
        "app_name": "Audible"},
    "auth_data": {
        "client_id" : client_id,
        "authorization_code" : authorization_code,
        "code_verifier" : code_verifier,
        "code_algorithm" : "SHA-256",
        "client_domain" : "DeviceLegacy"
    },
    "requested_extensions": ["device_info", "customer_info"]
  }

The client_id can be created from the serial with the function
audible.login.build_client_id(serial).

from audible.

W-rakuda avatar W-rakuda commented on May 23, 2024

Looks like amazon stopped accepting token requests, the old method fails now. The new method outlined above seems to succeed, but I am unable to log in because Audible asks for the password and captcha a second time for security purposes.

from audible.

mkb79 avatar mkb79 commented on May 23, 2024

I‘m still on vacation for a few days. Will look on this later. Maybe you have provided a wrong password? Which error message are printed out?

from audible.

W-rakuda avatar W-rakuda commented on May 23, 2024

I'm sure the password is correct, but after implementing the changes you outlined above I have gotten to the point where (from checking the log after failure) amazon asks to check a second captcha and input the password one more time. However, the code doesn't seem to handle this, and it fails to log in.

I have also tried to use external_login. The login through the web-browser succeeds, but the script fails when processing the pasted url. The error I get is "KeyError: 'openid.oa2.access_token'", and in the url I have "openid.oa2.authorization_code".

from audible.

mkb79 avatar mkb79 commented on May 23, 2024

Yeah, the code for external login must be rewritten to use the code challenge URL.

from audible.

W-rakuda avatar W-rakuda commented on May 23, 2024

By the way, for when you look into this later, this was on the jp-region store.

from audible.

mkb79 avatar mkb79 commented on May 23, 2024

I‘m working to implement the auth_code flow to my package. Take a look on this branch for current progress.

from audible.

W-rakuda avatar W-rakuda commented on May 23, 2024

Update: as I was testing things out, it looks like the JP marketplace started issuing access_token again, and I was able to authorize using both external_login as well as the cli. But I guess it's just a matter of time before they remove them permanently.

from audible.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.