mopidy / mopidy-spotify

Mopidy extension for playing music from Spotify
https://mopidy.com/ext/spotify/
Apache License 2.0
932 stars 108 forks source link

Spotify disabled username/password authentication #394

Open kingosticks opened 1 month ago

kingosticks commented 1 month ago

Jump to workarounds: https://github.com/mopidy/mopidy-spotify/issues/394#issuecomment-2285831264


noting that Spotify disabled username/password authentication, which affects playback in 2024 on the https://github.com/mopidy/mopidy-spotify/tree/v5.0.0alpha branch,

users will see errors similiar to failed to start: Login failed with reason: Bad credentials

ERROR        spotifyaudiosrc audio/spotify/src/spotifyaudiosrc/imp.rs:328:gstspotify::spotifyaudiosrc::imp:<source> failed to start: Login failed with reason: Bad credentials
WARN                 basesrc gstbasesrc.c:3134:gst_base_src_loop:<source> error: Internal data stream error.
WARN                 basesrc gstbasesrc.c:3134:gst_base_src_loop:<source> error: streaming stopped, reason error (-5)
WARN                oggdemux gstoggdemux.c:4775:gst_ogg_demux_send_event:<oggdemux0> error: EOS before finding a chain
WARN                oggdemux gstoggdemux.c:2550:gst_ogg_demux_sink_event:<oggdemux0> EOS while trying to retrieve chain, seeking disabled

since this is an upstream issue with https://github.com/librespot-org/librespot/issues/1308 a solution will be multi-tiered,

as always, ty @kingosticks, for your work on this

Originally posted by @troyxmccall in https://github.com/mopidy/mopidy-spotify/issues/110#issuecomment-2284230854


Thanks for adding this here also.

I would have thought things will continue to work for existing users because we support "cached credentials". Only the very first login actually uses your user and password. This does assume you are persisting the contents of Mopidy's data_dir where we store that blob. The default config location should ensure that's the case. I can replicate the problem if I move my cached creds elsewhere but it's still working otherwise.

Obtaining cached credentials (via a custom build of librespot, or similar) and moving them into this directory is a work-around.

Originally posted by @kingosticks in https://github.com/mopidy/mopidy-spotify/issues/110#issuecomment-2284282360

kingosticks commented 1 month ago

As already mentioned, this ultimately needs fixing in librespot. I have submitted a PR there to do that, hopefully it'll be merged when the maintainer has time. I'd appreciate review/feedback anyone has on that work but please don't hassle them there, everyone is busy and it's holiday season too - thanks Spotify! Once that (or something like it) is merged, we'll need to get support into gst-plugin-spotify. Depending what that support looks like, we may then also need to make changes to Mopidy-Spotify. As you can see, there are multiple projects involved so don't expect this to happen tomorrow. We could provide a custom build but I am reluctant because I'm not sure what gst-plugin-spotify will look like and I don't want to support another version of everything, even if it is short-term.

In the meantime, there is a workaround. You ultimately need to obtain a "cached credentials" file and drop this into your Mopidy-Spotify data directory (typically $HOME/.local/share/mopidy/spotify/credentials-cache/credentials.json or /var/lib/mopidy/spotify/credentials-cache/credentials.json). You can generate this file by running librespot and authenticating via "discovery" mode (AKA zeroconf).

  1. Download rust and clone librespot.
  2. From the librespot directory do cargo run --no-default-features -- --cache .
  3. Use an official Spotify app (on the same network) to connect to the running librespot device using Spotify Connect
  4. You'll then find a new credentials.json file in the librespot directory that looks something like
    {"username":"fred","auth_type":1,"auth_data":"LOADOFSEEMINGLYRANDOMCHARACTERSBLAHBLAGBWOOTWOOt=="}
  5. Copy this file into the appropriate Mopidy-Spotify directory as mentioned above.

If you cannot use Spotify Connect for whatever reason, you could clone my librespot branch instead and get your credentials.json via the new OAuth flow with cargo run --no-default-features -- --cache . --token "".

phuketbinaryt commented 1 month ago

As already mentioned, this ultimately needs fixing in librespot. I have submitted a PR there to do that, hopefully it'll be merged when the maintainer has time. I'd appreciate review/feedback anyone has on that work but please don't hassle them there, everyone is busy and it's holiday season too - thanks Spotify! Once that (or something like it) is merged, we'll need to get support into gst-plugin-spotify. Depending what that support looks like, we may then also need to make changes to Mopidy-Spotify. As you can see, there are multiple projects involved so don't expect this to happen tomorrow. We could provide a custom build but I am reluctant because I'm not sure what gst-plugin-spotify will look like and I don't want to support another version of everything, even if it is short-term.

In the meantime, there is a workaround. You ultimately need to obtain a "cached credentials" file and drop this into your Mopidy-Spotify data directory (typically $HOME/.local/share/mopidy/spotify/credentials-cache/credentials.json or /var/lib/mopidy/spotify/credentials-cache/credentials.json). You can generate this file by running librespot and authenticating via "discovery" mode (AKA zeroconf).

  1. Download rust and clone librespot.
  2. From the librespot directory do cargo run --no-default-features -- --cache .
  3. Use an official Spotify app (on the same network) to connect to the running librespot device using Spotify Connect
  4. You'll then find a new credentials.json file in the librespot directory that looks something like
{"username":"fred","auth_type":1,"auth_data":"LOADOFSEEMINGLYRANDOMCHARACTERSBLAHBLAGBWOOTWOOt=="}
  1. Copy this file into the appropriate Mopidy-Spotify directory as mentioned above.

If you cannot use Spotify Connect for whatever reason, you could clone my librespot branch instead and get your credentials.json via the new OAuth flow with cargo run --no-default-features -- --cache . --token ''.

I am getting this error when trying the last option: Error parsing command line options: Unrecognized option: 'token'

kingosticks commented 1 month ago

Does 'token' appear as an option when you run with --help? If not, you're not using my fork. Also note the version should be '0.5.0-dev 27b2b59'.

cargo run --no-default-features -- -c . --help
...
librespot 0.5.0-dev 27b2b59 (Built on 2024-08-13, Build ID: 2q9wcmIs, Profile: debug)

An open source client library for Spotify, with support for Spotify Connect

https://github.com/librespot-org/librespot

Usage: target\debug\librespot.exe [<Options>]

Options:
...
    -k, --token TOKEN   Spotify access token to sign in with. Use empty string
                        to obtain token.
phuketbinaryt commented 1 month ago

Looks like cloning the git was giving me the wrong version indeed. Grabbed the zip and that sorted it all out. Thanks, working great now.

pvincent4 commented 4 weeks ago

Thanks a lot for this quick fix. Surprisingly it worked well yesterday adding manualy the credentials.json to my local folder... but today I get this error starting mopidy and its extensions : pi mopidy[13812]: ERROR [SpotifyBackend-9] mopidy_spotify.web OAuth token refresh failed: invalid_grant Grant has been revoked. pi mopidy[13812]: ERROR [SpotifyBackend-9] mopidy_spotify.web Failed to load Spotify user profile

I retried the procedure without success, a bit weird... Is somebody experiencing a similar issue?

PS : I guessed that values ​in mopidy.conf ​are not supposed to be removed (username, password, client_id, client_secret)

kingosticks commented 4 weeks ago

PS : I guessed that values ​in mopidy.conf ​are not supposed to be removed (username, password, client_id, client_secret)

The username and password fields won't actually be used once you've got a credentials.json in place. The client_id and client_secret might need updating if Spotify have reset your credentials? These are used by the mopidy_spotify.web module to access your account data. You can get new ones at https://mopidy.com/ext/spotify/

geheim27 commented 4 weeks ago

Hi, I tried the Spotify Connect workaround but unfortunately without success. Is there any log entry to verify the use of the credentials.json file by Mopidy? Thanks

kingosticks commented 4 weeks ago

No. You could try the gstreamer logs: GST_DEBUG=3,*spotify*:6 mopidy.

pvincent4 commented 4 weeks ago

The username and password fields won't actually be used once you've got a credentials.json in place. The client_id and client_secret might need updating if Spotify have reset your credentials? These are used by the mopidy_spotify.web module to access your account data. You can get new ones at https://mopidy.com/ext/spotify/

Well done, I reset the values ​​and that fixed the problem. Cheers

geheim27 commented 4 weeks ago

Found my problem. Within mopidy.conf, I had the spotify login mail address but credentials.json contained the spotify username. Updated mopidy.conf and now its working.

kingosticks commented 4 weeks ago

Oh, excellent find. Thanks

davestroker commented 3 weeks ago

Thanks @kingosticks for your work. Unfortunatly i can not get it to work. I created the credentials.json on a windows machine and copied it to a linked folder on my server, where mopidy runs in a docker container. I also did an update of the clientID and secret. It still gives me the "bad credentials" error. Is it even possible to create the credentials on another machine or does it need to be the machine were mopidy runs? I gues then its not possible to do it within the container!? Thanks a lot!!!

kingosticks commented 3 weeks ago

I would guess it might need to be the same OS (e.g. windows, mac, Linux), because the client ID used to generate the credentials file is OS-specific. But that's a guess.

kingosticks commented 3 weeks ago

As per my early comment with workarounds, if you can't use zeroconf on your server, use my forked version and do the oauth flow in headless mode cargo run --no-default-features -- --cache . --token "" --token-port 0.

3052 commented 1 week ago

Spotify disabled username/password authentication

no, they didn't. you just have to specify user-agent

kingosticks commented 1 week ago

Great, thanks, that's super helpful.

PureTryOut commented 1 week ago

So steps for me to make this work were a combination of multiple things mentioned in this thread:

  1. get a new valid credentials.json using LibreSpot when connecting to it from an official Spotify client
  2. Update client_id and client_secret values from https://mopidy.com/ext/spotify/
  3. Update the username field in mopidy.conf from my email address to the username mentioned in credentials.json. It seems to be an auto-generated username, there is no way I would be able to guess or know it

I hope this process can be simplified again at some point in the future because this was a bit of a hassle :sweat_smile: