librespot-org / librespot

Open Source Spotify client library
MIT License
4.69k stars 573 forks source link

`get_token` fails using credentials obtained through FB auth flow #754

Open medwards opened 3 years ago

medwards commented 3 years ago

I have credentials through a modified version of https://github.com/hrkfdn/ncspot/pull/537 that uses a newly created client id and client secret (CLIENT_ID from here on out). These credentials authenticate:

[2021-05-24][14:45:53] [librespot_core::session] [INFO] Authenticated as "##########" !
[2021-05-24][14:45:53] [librespot_playback::audio_backend::pulseaudio] [INFO] Using PulseAudio sink with format: S16
[2021-05-24][14:45:53] [librespot_core::session] [INFO] Country: "DE"

However librespot is unable to get a token using these credentials:

[2021-05-24][14:45:53] [librespot_core::mercury] [WARN] error 403 for uri hm://keymaster/token/authenticated?client_id=CLIENT_ID&scope=user-read-private,playlist-read-private,playlist-read-collaborative,playlist-modify-public,playlist-modify-private,user-follow-modify,user-follow-read,user-library-read,user-library-modify,user-top-read,user-read-recently-played

I have a hacked up version of examples/get_token.rs that works off of these credentials instead of whats passed on the command line (see https://github.com/medwards/librespot/commit/fed29f4ceca9d4fedf49f251b1b7d9a0cdc74ed2).

This works for the streaming scope:

~/forks/librespot$ cargo run --package librespot --example get_token -- /home/medwards/.cache/ncspot/librespot CLIENT_ID streaming
    Finished dev [unoptimized + debuginfo] target(s) in 0.06s
     Running `target/debug/examples/get_token /home/medwards/.cache/ncspot/librespot CLIENT_ID streaming`
Connecting..
Token: Token {
    access_token: "AN_ACCESS_TOKEN",
    expires_in: 3600,
    token_type: "Bearer",
    scope: [
        "streaming",
    ],
}

For any other scope or combination of scopes I get MecuryError.

~/forks/librespot$ cargo run --package librespot --example get_token -- /home/medwards/.cache/ncspot/librespot CLIENT_ID playlist-modify
    Finished dev [unoptimized + debuginfo] target(s) in 0.06s
     Running `target/debug/examples/get_token /home/medwards/.cache/ncspot/librespot CLIENT_ID playlist-modify`
Connecting..
 Got error: MercuryError
~/forks/librespot$ cargo run --package librespot --example get_token -- /home/medwards/.cache/ncspot/librespot CLIENT_ID playlist-read
    Finished dev [unoptimized + debuginfo] target(s) in 0.06s
     Running `target/debug/examples/get_token /home/medwards/.cache/ncspot/librespot CLIENT_ID playlist-read`
Connecting..
 Got error: MercuryError

I originally requested the following scopes when going through the oauth2 flow so I expect these to work (and mysteriously streaming does):

                  "app-remote-control",
                  "playlist-modify",
                  "playlist-modify-private",
                  "playlist-modify-public",
                  "playlist-read",
                  "playlist-read-collaborative",
                  "playlist-read-private",
                  "streaming",
                  "user-follow-modify",
                  "user-follow-read",
                  "user-library-modify",
                  "user-library-read",
                  "user-modify",
                  "user-read-private",
                  "user-read-recently-played",
                  "user-top-read",
medwards commented 3 years ago

I made https://github.com/medwards/ncspot/tree/env-client-secrets if you want to reproduce your own credentials. However while setting it up I realized I was using the normal Spotify client id with my own client secret. If I use my client id and client secret for SPOTIFY_APP_CLIENT_ID then I can still authenticate however I can't get a token for any token in this case (incl. streaming). If I use the spotify desktop app client id as SPOTIFY_APP_CLIENT_ID and my client secret then you get the behaviour I described in the main body of the issue.

This might be expected behaviour, in which case feel free to close.

sashahilton00 commented 3 years ago

It's possible that the keymaster endpoint simply doesn't support OAuth2 clients and their tokens. Given that this service is essentially an interop service that allows mercury clients to consume the HTTP endpoints protected by OAuth, the devs at Spotify may have not seen the point of supporting oauth sessions in the oauth token generating keymaster.

With regards to the streaming scope working and no others, I believe the streaming scope is required to interact with mercury endpoints. I may be wrong on this though.

As for your client ID not working for streaming whilst Spotify's ID does work somewhat, it's possible that they do some form of whitelisting on their end.

It may be worth examining this behaviour further, but given the simplicity of the keymaster endpoint and what it does, combined with your observations around the behaviour with different client IDs, I'd place my bet on this being expected behaviour from Spotify servers rather than a bug, though the line is often blurred :)

gdesmott commented 1 year ago

Does this mean it's not possible to use librespot with tokens generated using the Authorization Code Flow ?