Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spotify Password Authentication Deprecated #1274

Open
goshansp opened this issue Aug 16, 2024 · 39 comments
Open

Spotify Password Authentication Deprecated #1274

goshansp opened this issue Aug 16, 2024 · 39 comments

Comments

@goshansp
Copy link

goshansp commented Aug 16, 2024

Describe the bug
Some users have been getting [Error] (librespot) could not initialize spirc: Permission denied { Login failed with reason: Bad credentials } in the past weeks. It seems that Spotify is deprecating password authentication as notified to Librespot.

It seems that snapcast needs to implement the new token based authentication mechanism as soon as this change in librespot gets merged.

Steps to Reproduce

  1. Configure Spotify Username & Password
  2. Start Snapcast

Environment details

  • OS: Fedora/Podman
  • Snapcast version 0.28.0
  • Container Image ghcr.io/firefrei/snapcast/server:latest
[Error] (librespot) could not initialize spirc: Permission denied { Login failed with reason: Bad credentials }
@awsome306
Copy link

Is there anything to do in the meantime? Or is it just to wait until the changes get merged?

@acaliebe
Copy link

Try to Play with zeroconf - without username and password. -- and wait for Librespot to solve the problem.

/usr/bin/librespot --name MyLibrespotSpeaker --bitrate 320 --backend pipe --cache /var/cache/librespot --initial-volume 100 --verbose

[2024-08-19T12:18:50Z INFO librespot] librespot 0.5.0-dev 299b7de (Built on 2024-08-14, Build ID: OsvPSZhj, Profile: release)
[2024-08-19T12:18:50Z TRACE librespot] Command line argument(s):
[2024-08-19T12:18:50Z TRACE librespot] name "MyLibrespotSpeaker"
[2024-08-19T12:18:50Z TRACE librespot] bitrate "320"
[2024-08-19T12:18:50Z TRACE librespot] backend "pipe"
[2024-08-19T12:18:50Z TRACE librespot] cache "/var/cache/librespot"
[2024-08-19T12:18:50Z TRACE librespot] initial-volume "100"
[2024-08-19T12:18:50Z TRACE librespot] onevent "/usr/bin/librespot_event"
[2024-08-19T12:18:50Z TRACE librespot] verbose
[2024-08-19T12:18:50Z TRACE librespot] Using cached credentials.
[2024-08-19T12:18:50Z DEBUG librespot_core::session] new Session
[2024-08-19T12:18:50Z DEBUG librespot_discovery::server] Zeroconf server listening on 0.0.0.0:34245
[2024-08-19T12:18:50Z INFO librespot_playback::mixer::softmixer] Mixing with softvol and volume control: Log(60.0)
[2024-08-19T12:18:50Z DEBUG librespot_playback::player] new Player [0]
[2024-08-19T12:18:50Z DEBUG librespot_connect::spirc] new Spirc[0]
[2024-08-19T12:18:50Z INFO librespot_playback::convert] Converting with ditherer: tpdf
[2024-08-19T12:18:50Z DEBUG librespot::component] new MercuryManager
[2024-08-19T12:18:50Z INFO librespot_playback::audio_backend::pipe] Using StdoutSink (pipe) with format: S16
[2024-08-19T12:18:50Z DEBUG librespot::component] new ApResolver
[2024-08-19T12:18:50Z DEBUG librespot_core::http_client] Requesting https://apresolve.spotify.com/?type=accesspoint&type=dealer&type=spclient
[2024-08-19T12:18:50Z DEBUG librespot_playback::player] command=AddEventSender
[2024-08-19T12:18:51Z INFO librespot_core::session] Connecting to AP "ap-gew4.spotify.com:4070"
[2024-08-19T12:18:51Z INFO librespot_core::session] Authenticated as "anycryptedname" !
[2024-08-19T12:18:51Z DEBUG librespot_connect::spirc] canonical_username: anycryptedname
[2024-08-19T12:18:51Z DEBUG librespot_playback::player] command=AddEventSender
[2024-08-19T12:18:51Z DEBUG librespot_core::mercury] listening to uri=hm://remote/user/
[2024-08-19T12:18:51Z DEBUG librespot_core::mercury] listening to uri=spotify:user:attributes:update
[2024-08-19T12:18:51Z DEBUG librespot_core::mercury] listening to uri=spotify:user:attributes:mutated
[2024-08-19T12:18:51Z DEBUG librespot_core::mercury] listening to uri=hm://pusher/v1/connections/
[2024-08-19T12:18:51Z DEBUG librespot_core::session] Session strong=4 weak=4
[2024-08-19T12:18:51Z INFO librespot_core::session] Country: "DE"
[2024-08-19T12:18:51Z TRACE librespot_core::session] Received product info: ....

Snapserver source sample ( in /etc/snapserver.conf ):
source = spotify:///librespot?name=Spotify&dryout_ms=2000&wd_timeout=7800&controlscript=librespot_meta.sh&devicename=MySnapServer&cache=/var/cache/librespot&cache-size-limit=2G&onevent=/usr/bin/librespot_event&bitrate=320&volume=100&killall=true

notes:

  • I have to restart snapserver-service after playback ends.
  • If you hear noice when transfer the speaker via the win-Player, restart and retry.

@bai-yi-bai
Copy link

I just wanted to report that I am a snapcast user and I had my Spotify account disabled due to password-based credentials being deprecated by what I suppose is either my Home Assistant snapcast integration or snapcast server hammering spotify trying to log in . I had the same [Error] (librespot) could not initialize spirc: Permission denied { Login failed with reason: Bad credentials }.
I used acaliebe's suggestion:

  1. Go to spotify to request a password reset.
  2. [Fixing Home Assistant] I re-copied the client id and client secret using Home Assistant's nifty integration which uses URLs https://www.home-assistant.io/integrations/spotify
  3. [Android App] I had to clear the cache and database otherwise, I couldn't log in, I had three large dots.
  4. [snapserver.conf] I removed the ?username= and ?password= portions
  5. I started playback and had to restart a couple clients

@milnivlek
Copy link

@bai-yi-bai - Thanks for sharing your experience. I am also using Home Assistant to initiate playback on Snapcast. If you remove the credentials from the Snapcast config, then won't your Snapcast Spotify Connect source get unlinked from your Spotify account after being inactive for some time? How are you able to keep Snapcast in the list of Spotify Connect sources via Home Assistant?

@rwjack
Copy link

rwjack commented Aug 20, 2024

I think he meant like he removed those portions and made his peace that Spotify is trash and that we should all look into playing music locally and not through their garbage API

@bai-yi-bai
Copy link

@bai-yi-bai - Thanks for sharing your experience. I am also using Home Assistant to initiate playback on Snapcast. If you remove the credentials from the Snapcast config, then won't your Snapcast Spotify Connect source get unlinked from your Spotify account after being inactive for some time? How are you able to keep Snapcast in the list of Spotify Connect sources via Home Assistant?

The Home Assistant Spotify API uses the developer credentials (client ID/client secret) set up in the Spotify developer portal. I don't think it ever used username and password credentials. I simply had to "cycle" it to re-establish the link.

I think he meant like he removed those portions and made his peace that Spotify is trash and that we should all look into playing music locally and not through their garbage API

LOL - Yes, my first thought was to see if Snapcast supported any other streaming services, but for me the recommendation algorithm has been a great way to discover new music and new genres.

@rwjack
Copy link

rwjack commented Aug 21, 2024

Yes... The recommendation algorithm... It's the only thing keeping that ship afloat

@fraintt
Copy link

fraintt commented Aug 25, 2024

I can also confirm that in the last weeks my Spotify Password was reset due to suspicious activity and therefor I also was not able to login with librespot also with changed credentials.

@3052
Copy link

3052 commented Aug 31, 2024

Spotify Password Authentication Deprecated

its not. the current Spotify Android client definitely still support email/password, Ive been testing it all day. in fact my code from last month still works as is, if you add a user-agent

@manuelkue
Copy link

@3052

if you add a user-agent

Do you mean with Snapcast / librespot?
Could you please elaborate, how to set a user-agent?

@3052
Copy link

3052 commented Sep 1, 2024

I have an implementation here if it helps

https://github.com/3052/platform/tree/v1.4.9/spotify

@c13github-ir
Copy link

I built an OS image based on Snapcast (just so I could give "whole-house audio" systems to non-technical people for birthdays, holidays, etc.). What worked for me was to use the librespot build from dtcooper's Raspotify (https://dtcooper.github.io/raspotify/). The OS image I built is Debian-based, so I:

  • installed dtcooper's deb package
  • disabled the raspotify system service
  • configured snapserver to use librespot as its source:
# devicename is how it shows up in Spotify; name is how the group shows up in Snapcast
source = librespot:///usr/bin/librespot?name=DESIRED_SNAPCAST_GROUP_NAME&devicename=DESIRED_SPOTIFY_DEVICE_NAME

Then zeroconf magic takes care of the rest: I sign in to Spotify on another device (Spotify client or web browser) and it sees DESIRED_SPOTIFY_DEVICE_NAME as an available device for playback.

@rwjack
Copy link

rwjack commented Sep 1, 2024

Wait so zeroconf actually works? Why tf are we busting our nuts trying to configure credentials.json and whatnot as per: librespot-org/librespot#1308 (comment)

@milnivlek
Copy link

In my case, it's helpful because I use my home autoomation to programmatically initiate playbacks on my Snapcast source, without using the Spotify app. Since ZeroConf logins expire after some period of inactivity (~10 min I think?), it's helpful to just permanently associate the Snapcast source with my Spotify account so that it never disappears from my list of Spotify Connect devices.

@sadziu82
Copy link

sadziu82 commented Sep 1, 2024

I used librespot-auth to generate my credentials.json. Then I copied it into /var/cache/librespot/<STREAM_NAME>/credentials.json and restarted snapserver - it's working for a few days now without issues. I just had to remove username and password from stream definition.

@fraintt
Copy link

fraintt commented Sep 2, 2024

Wait so zeroconf actually works? Why tf are we busting our nuts trying to configure credentials.json and whatnot as per: librespot-org/librespot#1308 (comment)

Because I also want to:

  • start playing on Spotify programmatically
  • start playing on Spotify at home when I´m not on the local LAN (Speaker is "bound" to my account)

If you only want to use spotify "locally" on the local LAN/Wifi, then you do not need to pass any credentials

@c13github-ir
Copy link

In my case, it's helpful because I use my home autoomation to programmatically initiate playbacks on my Snapcast source, without using the Spotify app. Since ZeroConf logins expire after some period of inactivity (~10 min I think?), it's helpful to just permanently associate the Snapcast source with my Spotify account so that it never disappears from my list of Spotify Connect devices.

Yeah, this only handles playback, not control. For control, there are a bunch of projects out there (I used to use https://gist.github.com/wandernauta/6800547) - but then you're back to having to deal with credentials again. Basically, exactly what @fraintt said.

Re: the ZeroConf login expiration, thanks - I wasn't aware of that. I haven't had any issues running for weeks at a time, but I also haven't needed to have Spotify reconnect to devices when I'm no longer on the same network as them.

@rwjack
Copy link

rwjack commented Sep 2, 2024

@fraintt oh riiight, I need that functionality as well, so good thing I got it working then.

@fraintt
Copy link

fraintt commented Sep 4, 2024

I used librespot-auth to generate my credentials.json. Then I copied it into /var/cache/librespot/<STREAM_NAME>/credentials.json and restarted snapserver - it's working for a few days now without issues. I just had to remove username and password from stream definition.

Hi, I did the same, I have credentials.json but for me it still does not work.. I do not see the Spotify device when not connected to the local LAN. I also do not see anything in the Logs. At start I saw that there were permissions issues accessing the Path, which I fixed by changing ownership. How does your stream link/path look like? Have you specified any cache?

Also, I´m using raspotify, as librespot seems to be abandoned (last release 2 years ago. (i know, raspotify is also not u2date but I had better experience with raspotify)

@sadziu82
Copy link

Hi @fraintt

How does your stream link/path look like? Have you specified any cache?

source = spotify:///librespot?name=<STREAM_NAME>&devicename=<SPEAKER_NAME>&cache=/var/cache/librespot/<STREAM_NAME>&disable_audio_cache=false&killall=false

@fraintt
Copy link

fraintt commented Sep 19, 2024

I did exactly the same, but I cannot see the Speaker when I´m not on a local LAN.
What are your permissions on /var/cache/librespot/Spotify?

@sadziu82
Copy link

Both directory and credentials.json must be accessible (rx and r accordingly) by user running snapserver. Nothing special other than that. Check logs for Authenticated as "xxxxxxx" ! - that would mean librespot was able to login to your Spotify account.

@jaypi95
Copy link

jaypi95 commented Sep 20, 2024

@fraintt I had to build librespot directly from source because it didn't work for me otherwise. I am running librespot 0.5.0-dev e9234d3

The credentials.json is in /var/cache/librespot and accessible by snapserver as is the rest of that directory.

@fraintt
Copy link

fraintt commented Oct 3, 2024

Ok, great news. I failed at building librespot from source, but I´m using raspotify.
After setting the correct permissions on the cache Folder+File it is working.

Thanks for the help.

@ncsufan8628
Copy link

ncsufan8628 commented Oct 15, 2024

librespot-org/librespot#1340

I was having this issue - posted steps here to correctly build (if you are like me and have little knowledge of how these things work) so we can have working librespot. Changed authentication also breaks the spotify connect keep-alive mechanism and even if you get auth working, it will drop every 5-10m until you incorporate the fix mentioned here.

@kingosticks
Copy link
Contributor

kingosticks commented Nov 2, 2024

Librespot v0.6 should have connection and auth issues solved, upgrade if you're experiencing issues.

It's been a turbulent few months but Librespot now provides multiple way to login, these are documented in the librespot wiki. Ideally a project like this would pick one as the standard method it uses,.just to simplify things.

@artmg
Copy link
Contributor

artmg commented Nov 10, 2024

I will PR these into https://github.com/badaix/snapcast/blob/develop/doc/configuration.md#librespot shortly but here are the steps to use OAuth with librespot.

install librespot

If you choose to install librespot locally onto your host by using cargo, then you might find these instructions help you get configured. You will need to have the rust compiler and cargo package manager installed already. For other cases such as running librespot within a docker container, you should refer to the main librespot project documentation.

# prepare the librespot dependencies for your own OS
# this example is for debian bookworm and librespot 0.6.0
sudo apt install -y build-essential libasound2-dev cmake libclang-dev

# install and build the latest version of librespot from crates
cargo install librespot
# that command may take some time to download and compile 260 units
  
# finally, place the binary you just compiled into a common system path
sudo cp ~/.cargo/bin/librespot /usr/local/bin/

Authenticate your Spotify account

Spotify has deprecated password login, so we suggest you use the new Headless OAuth to authenticate your Spotify account.

sudo -u snapserver librespot --cache /var/lib/snapserver --enable-oauth --oauth-port 0
  • copy the Browse to: url to into any browser from where you can access the Spotify account
    • You are asked to 'Allow Spotify', so click the button to 'Continue to the app'
  • you WILL get a 'Connection Refused' error, which is fine :)
    • now simply copy the entire url from your browser address bar and paste it back into the command line where prompted Provide redirect URL
  • wait for the authentication to show in the command line
    • CTRL C to break
  • the credentials should now be in place with snapserver having access
    • to check sudo ls -la /var/lib/snapserver/
    • to correct if notsudo chown -R snapserver:snapserver /var/lib/snapserver

Configure your snapserver file

  • sudo vi /etc/snapserver.conf
  • remove username and password
  • the snapserver will give librespot it's credentials 'automatically' from the default cache location
    • the cache location was specified above on the librespot --enable-oauth line
    • if you use a different location, you may specify the path in the source = config
      • but bear in mind you may need to urlencode the slashes
        • e.g. &cache=%2Fvar%2Fcache%2Flibrespot%2F

example config, which no longer requires ANY authentication because it's now baked in

source = spotify:///librespot?name=Spotify&devicename=MyLibreSpot&bitrate=320&volume=35

@kingosticks
Copy link
Contributor

I think this is good except what about changing ownership of /var/lib/snapserver first and then running librespot --cache /var/lib/snapserver --enable-oauth --oauth-port 0 as user snapserver, rather than the root user?

@uSpike
Copy link
Contributor

uSpike commented Nov 12, 2024

Hi @fraintt

How does your stream link/path look like? Have you specified any cache?

source = spotify:///librespot?name=<STREAM_NAME>&devicename=<SPEAKER_NAME>&cache=/var/cache/librespot/<STREAM_NAME>&disable_audio_cache=false&killall=false

This doesn't work for me, I have to encode the forward slashes:

source = spotify:///librespot?name=<STREAM_NAME>&devicename=<SPEAKER_NAME>&cache=%2Fvar%2Fcache%2Flibrespot%2F

just FYI

@artmg
Copy link
Contributor

artmg commented Nov 12, 2024

Thanks @uSpike I'll make the point that if someone chooses a location to store the credentials that is not the execute location (e.g. /var/lib/snapserver) then they may have to urlencode the slashes in the path in their source definition

@neekz0r
Copy link

neekz0r commented Nov 15, 2024

Authenticate your Spotify account

Spotify has deprecated password login, so you must use new Headless OAuth to authenticate your Spotify account.

sudo librespot --cache /var/lib/snapserver --enable-oauth --oauth-port 0
* copy the `Browse to:` url to into any browser from where you can access the Spotify account

So in running in docker, I don't get a "browse to" output.

All I get is its version:

root@488a90698c63:/#  librespot --cache /var/lib/snapserver --enable-oauth --oauth-port 0
librespot 0.6.0 VERGEN_IDEMPOTENT_OUTPUT (Built on 2024-11-15, Build ID: tVAkh5ZJ, Profile: release)

TMK, 0.6.0 is the latest build; how are you getting the 'browse to' output you are referencing?

@artmg
Copy link
Contributor

artmg commented Nov 15, 2024

That's a very interesting question @neekz0r but perhaps one you might find best addressed over on the librespot project itself. Your issue will be not merely how to get the console output from docker but also how to persist the credentials. I'd imagine that a sensible way would be to run the authentication in a folder on the docker host, so that the files persist, and then mount that folder as a volume into the container so that it is available to the librespot executable when you docker run it.

As I say, you are most likely to find concrete examples of Headless OAuth using librespot in docker on the librespot's own project docs, wiki or issues. But do feel free to post here any examples or links you find in case others also look. Good luck

@neekz0r
Copy link

neekz0r commented Nov 15, 2024

That's a very interesting question @neekz0r but perhaps one you might find best addressed over on the librespot project itself. Your issue will be not merely how to get the console output from docker but also how to persist the credentials. I'd imagine that a sensible way would be to run the authentication in a folder on the docker host, so that the files persist, and then mount that folder as a volume into the container so that it is available to the librespot executable when you docker run it.

As I say, you are most likely to find concrete examples of Headless OAuth using librespot in docker on the librespot's own project docs, wiki or issues. But do feel free to post here any examples or links you find in case others also look. Good luck

I was more asking you to clarify the steps above since I can't duplicate what you outlined -- I don't see a "browse to" anywhere. I'm not sure if that is due to it being in docker, or if something else is going on. If the response is "not our problem, that's a librespot problem", fair enough! :-) I latched onto your response because the thread that was talking about this issue on librespot was closed because it turned into a flame war.

I would say, then, that updating the readme is "see librespot for how to authenticate" rather than step-by-step instructions is a better recourse.

@kingosticks
Copy link
Contributor

There are multiple ways to auth librespot so picking one here, with step by step instructions is a good idea, in my opinion.

I can't explain why your console output only contains a single line, that makes no sense. My guess is it's somehow due to using Docker. Try without docker.

@curiousercreative
Copy link

@neekz0r how did you get the shell to your docker container? My only trouble using docker was that librespot tries to identify an audio device and at I needed to pass through /dev/snd as device. Even with this problem I describe, librespot was outputting much more than what you see, including the error message indicating an audio device wasn't found.

@artmg
Copy link
Contributor

artmg commented Nov 16, 2024

I think this is good except what about changing ownership of /var/lib/snapserver first and then running librespot --cache /var/lib/snapserver --enable-oauth --oauth-port 0 as user snapserver, rather than the root user?

thanks @kingosticks I have tested and updated the comments above with your suggestion too

@neekz0r
Copy link

neekz0r commented Nov 17, 2024

@neekz0r how did you get the shell to your docker container? My only trouble using docker was that librespot tries to identify an audio device and at I needed to pass through /dev/snd as device. Even with this problem I describe, librespot was outputting much more than what you see, including the error message indicating an audio device wasn't found.

Standard way; docker exec -it container_name /bin/bash -- i didn't override the entrypoint because its a custom docker image and the entry point is a bash script I wrote that does a few other things.

So to clarify, when you ran the above command in docker it did give you a browse to output somewhere? Could you tell me your version, and perchance, what method you used to install librespot?

edit: I also ran it by overriding the entrypoint to /bin/bash and I received the same results. So its not like its conflicting with a background process somewhere.

@curiousercreative
Copy link

@neekz0r this is my Dockerfile, I get a shell same as you once a container is created and the command I ran was the same (different cache location, but shouldn't matter)

FROM python:3-alpine

ARG LIBRESPOT_VERSION=0.6.0-r0
ARG SNAPCAST_VERSION=0.29.0-r0

RUN echo "https://dl-cdn.alpinelinux.org/alpine/edge/testing/" >> /etc/apk/repositories \
  && echo "https://dl-cdn.alpinelinux.org/alpine/edge/community/" >> /etc/apk/repositories
RUN apk add --no-cache bash snapcast=${SNAPCAST_VERSION} librespot=${LIBRESPOT_VERSION}
RUN pip3 install python-mpd2 musicbrainzngs websocket-client

CMD snapserver

@neekz0r
Copy link

neekz0r commented Nov 29, 2024

The above dockerfile worked for me, but strangely alpine:3.20.3 did not -- there is something magical that the python based image is doing.

I've created a bug over at librecast, but I wanted to thank you @curiousercreative -- that was really helpful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests