PromyLOPh / pandora-apidoc

pandora.com API documentation
https://6xq.net/pandora-apidoc/
Do What The F*ck You Want To Public License
48 stars 19 forks source link

Stub out REST API docs #26

Closed mcrute closed 6 years ago

mcrute commented 6 years ago

Pandora has a new REST-ish API that all of the official clients use that is different (and decidedly less esoteric) than the currently documented JSON v5 API. This change stubs out the docs for at least the basic authentication and login stuff that I've been able to verify. I'll add more docs as I get time but opening a pull request now to increase visibility in case somebody else wants to help with the documentation effort.

FireController1847 commented 6 years ago

I might actually be able to connect for once o.o

PromyLOPh commented 6 years ago

Finally. Do you know when the switch happened for mobile (Android/iOS) applications? Last time I checked it still used tuner.pandora.com.

A few remarks:

1) Endpoint for login is wrong, should be /v1/auth/login 2) My first request failed with {"message":"Invalid ContentType: application/x-www-form-urlencoded","errorCode":0,"errorString":"INVALID_REQUEST"}, which can be fixed by adding the header Content-Type: application/json;charset=utf-8. This requirement should be documented. 3) Even with this header login does not work for me: {"message":"The request could not be validated","errorCode":0,"errorString":"INVALID_REQUEST"} Anything else missing? (I included X-CsrfToken) 4) The page “implementations” should be shared by both API’s.

mcrute commented 6 years ago

I didn't dig too deep into the Android app, I know it uses some functionality that doesn't appear to be available in tuner. But I could be wrong. The website is definitely using this new API.

I fixed the errors you noted, sorry, late-night typos. I've also attached the working python code I was using to poke at this new API. Can you give me more details around what you're testing in 3? To login you need a CSRF token in a cookie and a header. After login you need a CSRF token as before but also an AuthToken header as pulled from the login response. Originally I thought you needed to keep a cookiejar of service issued cookies but that may not actually be the case.

import requests

ses = requests.session()
ses.head("https://www.pandora.com/")

csrf = ses.cookies["csrftoken"]
req = {
    "existingAuthToken": None,
    "username": "email@example.com",
    "password": "password",
    "keepLoggedIn": True
}

data = ses.post(
    "https://www.pandora.com/api/v1/auth/login", json=req,
    headers={"X-CsrfToken": csrf, "X-AuthToken": ""})

at = data.json()["authToken"]
data = ses.post(
    "https://www.pandora.com/api/v1/station/getStations",
    json={"pageSize":250}, headers={"X-CsrfToken": csrf, "X-AuthToken": at})

print(data.text)
mcrute commented 6 years ago

Here's a version with curl that works. I guess there is no need to keep track of cookies after all. Fetching the CSRF token from Pandora isn't mandatory either they only compare that they're equal.

CSRFTOKEN=$(curl -sI https://www.pandora.com | egrep -o 'csrftoken=[^;]+')

curl \
    --data '{"username":"me","password":"password"}' \
    -H "Cookie: csrftoken=$CSRFTOKEN" \
    -H "X-CsrfToken: $CSRFTOKEN" \
    -H 'Content-Type: application/json' \
    https://www.pandora.com/api/v1/auth/login

curl \
    --data '{"pageSize":250}' \
    -H "Cookie: csrftoken=$CSRFTOKEN" \
    -H "X-CsrfToken: $CSRFTOKEN" \
    -H 'Content-Type: application/json' \
    -H 'X-AuthToken: from-previous-json' \
    https://www.pandora.com/api/v1/station/getStations
FireController1847 commented 6 years ago

When/How will we see this implemented in the website? (Like, how do I navigate to it, and has it taken place yet?)

PromyLOPh commented 6 years ago

It’s up now.