Skip to content

[4.0.0] Authentication error 400 #2494

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

Closed
1 of 2 tasks
Patrick010 opened this issue Mar 14, 2025 · 113 comments
Closed
1 of 2 tasks

[4.0.0] Authentication error 400 #2494

Patrick010 opened this issue Mar 14, 2025 · 113 comments
Labels
bug Something isn't working deployed This issue has been fixed/implmented and has been released

Comments

@Patrick010
Copy link

Is there an existing issue for this? (Please read the description)

  • I have searched the existing issues

Current Behavior

I'm experiencing an Authentication error 400 when I start up Spotube. Everything seems to be working properly, except the bulk downloading of Spotify Playlists. And because this is the main reason for me to use Spotube to begin with, I find it a rather annoying one ;)

I run 4.0.0 on Win10

Is this a known issue?

Image

Expected Behavior

The app running without this error and the playlist download option in working order

Steps to reproduce

The error shows on start up

Logs

[2025-03-14 12:17:44.015229]---------------------
DioException [bad response]: This exception was thrown because the response has a status code of 401 and RequestOptions.validateStatus was configured to throw for this status code.
The status code of 401 has the following meaning: "Client error - the request contains bad syntax or cannot be fulfilled"
Read more about status codes at https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
In order to resolve this exception you typically have either to verify and fix your request code or you have to fix the server code.

#0 DioMixin.fetch (package:dio/src/dio_mixin.dart:520)

#1 CustomSpotifyEndpoints.getFriendActivity (package:spotube/services/custom_spotify_endpoints/spotify_endpoints.dart:113)

#2 FutureHandlerProviderElementMixin.handleFuture.. (package:riverpod/src/async_notifier/base.dart:355)


[2025-03-14 12:17:44.430059]---------------------
FormatException: Invalid number (at character 1)

^

#0 int._handleFormatError (dart:core-patch/integers_patch.dart:135)
#1 int.parse (dart:core-patch/integers_patch.dart:53)
#2 ServiceUtils.checkForUpdates (package:spotube/utils/service_utils.dart:353)

Operating System

Windows 10

Spotube version

v4.0.0

Installation source

Website (spotube.krtirtho.dev), GitHub Releases (Binary)

Additional information

No response

Self grab

  • I'm ready to work on this issue!
@Patrick010 Patrick010 added the bug Something isn't working label Mar 14, 2025
@Schoggiweggli
Copy link

Can confirm, same error 400 every start since 4.0.0 on Windows 10.

@binaryben

This comment has been minimized.

@KimDianis

This comment has been minimized.

@JohnSoellnerDev

This comment has been minimized.

@MIRAM69

This comment has been minimized.

@Arun0A
Copy link

Arun0A commented Mar 14, 2025

Yes, it fails to get the access token. Error: 400. Since 4.0.0 on Windows 11 x86-64.

@Strykerflash

This comment has been minimized.

@shadyx49

This comment has been minimized.

@bloomdevelop

This comment has been minimized.

@goiabae

This comment has been minimized.

@roycordero

This comment has been minimized.

@m4rc0s4p4r1c10

This comment has been minimized.

@777Vincent

This comment has been minimized.

@777Vincent

This comment has been minimized.

@777Vincent

This comment has been minimized.

@777Vincent

This comment has been minimized.

@777Vincent

This comment has been minimized.

@DRYN07
Copy link

DRYN07 commented Mar 14, 2025

I hope its just spotube and not spoti related. My friend used unofficial app and spoti deleted all of his playlists and other data...

@777Vincent
Copy link

I hope its just spotube and not spoti related. My friend used unofficial app and spoti deleted all of his playlists and other data...

I just checked by redownloading Spotify and logging in, all my information is here with no sign of any tweaks, flags, or deletions. It's unlikely Spotify would do something like that for spotube specifically because spotube doesn't use Spotify requests to get songs but rather uses YouTube and just uses your playlist data to generate playlists and recommendations from Spotify instead, which isn't against their terms

@Bluqui

This comment has been minimized.

@yellowduck134

This comment has been minimized.

@BezShkvark0

This comment has been minimized.

@BezShkvark0

This comment has been minimized.

@AlexDev404

This comment has been minimized.

@x29a
Copy link

x29a commented Mar 14, 2025

Please everybody refrain from writing "me too" or "same", instead provide information about your system, version, and the exact error message!

If you just want to state that you have the same problem, use the emojis like "thumbs up" on the first post. This will show the maintainers how urgent an issue is.

And please search if there are open issues regarding your problem instead of creating a new one!

Now to the issue at hand, this gets a lot of traction, i scrolled through the last 10 pages of issues and will link all authentication issues. @KRTirtho seems to be aware of this problem, as it was mentioned often enough.

Maybe spotify API changes are the culprit. Since its also happening with 3.9.0 and 3.8.3 of spotube. Could be this: https://developer.spotify.com/blog/2024-11-27-changes-to-the-web-api

Possible duplicates:

@AlexDev404
Copy link

AlexDev404 commented Mar 14, 2025

Please everybody refrain from writing "me too" or "same", instead provide information about your system, version, and the exact error message!

If you just want to state that you have the same problem, use the emojis like "thumbs up" on the first post. This will show the maintainers how urgent an issue is.

And please search if there are open issues regarding your problem instead of creating a new one!

Now to the issue at hand, this gets a lot of traction, i scrolled through the last 10 pages of issues and will link all authentication issues. @KRTirtho seems to be aware of this problem, as it was mentioned often enough.

Maybe spotify API changes are the culprit.

Possible duplicates:

That's what about more than half of us did, so I'm not sure what you're trying to get at.

EDIT: Please STOP moderating issues you have no permission to moderate. You seem to be very technically unaware, and are beginning to mark issues as "duplicate" which have no relation to this current issue at all by basing their "duplicate nature" just off of a few similar words.

@x29a x29a mentioned this issue Mar 14, 2025
2 tasks
@gollex
Copy link

gollex commented Mar 14, 2025

not sure it thats related, but maybe spotify did change the login routines, so spotube can't do the current login?
when doing a logout and trying to login isugin spotify i get this instead of working login:

Image

@Solid-Snake-99
Copy link

JUST by opening the app from clean install i get a bunch of errors. take the log please. don't put me as spam.

log spotube 4.0.1 android 10.txt

Another solution:

By @ThebigbossCE on Discord:

  • First, logout and clear data
  • Then, login with Spotify.
  • Once you logged in, it will not work, but it's fine. Go to Settings > User Profile, click "edit", it will open a new tab in your mobile browser (for me it was chrome). You'll see your spotify account on that browser. Simply hit logout, then login again. Once you did this, go back to spotube
  • logout and login to Spotify.

For some reason it will work now. I guess the browser login on Chrome renewed the access token and now it worked (not sure tho, I couldn't check the console, cookies and network requests since I'm on phone)

@Aro320x
Copy link

Aro320x commented Mar 15, 2025

Eine andere Lösung:

Von@ThebigbossCEauf Discord:

  • Melden Sie sich zunächst ab und löschen Sie die Daten
  • Melden Sie sich dann mit Spotify an.
  • Sobald du dich angemeldet hast, funktioniert es nicht mehr, aber es funktioniert einwandfrei. Gehe zu Einstellungen > Benutzerprofil und klicke auf „Bearbeiten“. Es öffnet sich ein neuer Tab in deinem mobilen Browser (bei mir war es Chrome). Dort siehst du dein Spotify-Konto. Klicke einfach auf „Abmelden“ und dann erneut auf „Anmelden“. Gehe anschließend zurück zu Spotube.
  • Melden Sie sich ab und wieder bei Spotify an.

Aus irgendeinem Grund funktioniert es jetzt. Ich vermute, die Browser-Anmeldung in Chrome hat den Zugriffstoken erneuert, und jetzt funktioniert es (bin mir aber nicht sicher, da ich die Konsole, Cookies und Netzwerkanfragen nicht überprüfen konnte, da ich am Telefon bin).

@Aro320x
Copy link

Aro320x commented Mar 15, 2025

I have tried your troubleshooting 3 times. Also uninstalled and reinstalled the app 3 times.
Unfortunately, the app doesn't even open anymore. First had 4.0.0 then the app still opened, but with error code 400.
Now 4.0.1. Doesn't work at all. Error code 429.
Android 14.

@gollex
Copy link

gollex commented Mar 15, 2025

i'm on arch linux.

login does seem to work with latest aur/spotube-bin, after i cleared ~/.cache/oss.krtirtho.spotube folder.
but my library etc. is not loaded.

logs:

spotube.zip

@KRTirtho KRTirtho changed the title Authentication error 400 [4.0.0] Authentication error 400 Mar 15, 2025
@KRTirtho
Copy link
Owner

Please anyone having the login issue after v4.0.1 continue the discussion in: #2525

@ServerDeveloper9447
Copy link

Another solution:

By @ThebigbossCE on Discord:

  • First, logout and clear data
  • Then, login with Spotify.
  • Once you logged in, it will not work, but it's fine. Go to Settings > User Profile, click "edit", it will open a new tab in your mobile browser (for me it was chrome). You'll see your spotify account on that browser. Simply hit logout, then login again. Once you did this, go back to spotube
  • logout and login to Spotify.

For some reason it will work now. I guess the browser login on Chrome renewed the access token and now it worked (not sure tho, I couldn't check the console, cookies and network requests since I'm on phone)

Damn... it works

@brrock
Copy link

brrock commented Mar 15, 2025

This is issue is ready to be closed fixed in

4.0.1

@brrock
Copy link

brrock commented Mar 15, 2025

That's from old version

@KRTirtho KRTirtho marked this as a duplicate of #2533 Mar 16, 2025
@KRTirtho
Copy link
Owner

Closing this as we've finally resolved the login issue

@github-project-automation github-project-automation bot moved this from Done to Deployed in Spotube Board Mar 17, 2025
@KRTirtho KRTirtho added the deployed This issue has been fixed/implmented and has been released label Mar 17, 2025
@KRTirtho KRTirtho marked this as a duplicate of #2557 Mar 17, 2025
@KRTirtho
Copy link
Owner

I'm leaving this Node.js typescript implementation to generate TOTP for the endpoint.
As a lot of projects are facing the same issues. And it'll be easier to read JS compared to Dart.
Btw, which ever programming language/library you use for generating TOTP, make sure it supports RFC4226 and RFC6238

In Dart we used , otp_util package which supports both RFCs

import { TOTP } from "totp-generator";

async function main() {

    const secretSauce = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
    const base32FromBytes = (e: Uint8Array) => {
        let t = 0;
        let n = 0;
        let r = "";
        for (let i = 0; i < e.length; i++) {
            n = n << 8 | e[i];
            t += 8;
            while (t >= 5) {
                r += secretSauce[n >>> t - 5 & 31];
                t -= 5;
            }
        }
        if (t > 0) {
            r += secretSauce[n << 5 - t & 31];
        }
        return r;
    }

    function cleanBuffer(e: string): Uint8Array<ArrayBuffer> {
        e = e.replace(/ /g, "");
        const t = new ArrayBuffer(e.length / 2);
        const n = new Uint8Array(t);
        for (let r = 0; r < e.length; r += 2) {
            n[r / 2] = parseInt(e.substring(r, r + 2), 16);
        }
        return n;
    };

    const secretCipherBytes = [12, 56, 76, 33, 88, 44, 88, 33, 78, 78, 11, 66, 22, 22, 55, 69, 54].map((e, t) => e ^ t % 33 + 9)

    const secretBytes = new Uint8Array((cleanBuffer(Buffer.from(secretCipherBytes.join(""), "utf8").toString("hex")).buffer));

    const secret = base32FromBytes(secretBytes);

    const res = await fetch("https://open.spotify.com/server-time").then((e) => e.json())
    const timestamp = res["serverTime"];

    const totp = TOTP.generate(secret, {
        algorithm: "SHA-1",
        digits: 6,
        period: 30,
        timestamp: timestamp * 1000,
    });

    const currentTimestamp = Math.floor(Date.now() / 1000);

    console.log("secretCipherBytes:", secretCipherBytes);
    console.log("secretBytes:", secretBytes);
    console.log("secret:", secret);
    console.log(`https://open.spotify.com/get_access_token?reason=transport&productType=web_player&totp=${totp.otp}&totpVer=5&ts=${currentTimestamp}`);
}

main();

@dcooper94
Copy link

i cant even get to the log on page, when i click log in a blank white page and the app crashes
LOGS

[2025-03-18 15:28:55.511757]---------------------
SqliteException(1): while executing, duplicate column name: youtube_client_engine, SQL logic error (code 1)
  Causing statement: ALTER TABLE "preferences_table" ADD COLUMN "youtube_client_engine" TEXT NOT NULL DEFAULT 'youtubeExplode';, parameters: 
package:sqlite3/src/implementation/exception.dart 75                         throwException
package:sqlite3/src/implementation/database.dart 244                         DatabaseImplementation.execute
package:drift/src/sqlite3/database.dart 145                                  Sqlite3Delegate.runWithArgsSync
package:drift/native.dart 378                                                _NativeDelegate.runCustom.<fn>
dart:async/future.dart 315                                                   new Future.sync
package:drift/native.dart 378                                                _NativeDelegate.runCustom
package:drift/src/runtime/executor/helpers/engines.dart 115                  _BaseExecutor.runCustom.<fn>
package:drift/src/runtime/executor/helpers/engines.dart 61                   _BaseExecutor._synchronized
package:drift/src/runtime/executor/helpers/engines.dart 111                  _BaseExecutor.runCustom
package:drift/src/remote/server_impl.dart 154                                ServerImplementation._runQuery
package:drift/src/remote/server_impl.dart 119                                ServerImplementation._handleRequest.<fn>
package:drift/src/remote/communication.dart 165                              DriftCommunication.setRequestHandler.<fn>
===== asynchronous gap ===========================
package:drift/src/remote/communication.dart 113                              DriftCommunication.request
package:drift/src/remote/client_impl.dart 101                                _BaseExecutor._runRequest
package:drift/src/remote/client_impl.dart 116                                _BaseExecutor.runCustom
package:drift/src/runtime/api/connection_user.dart 421                       DatabaseConnectionUser.customStatement.<fn>
package:drift/src/runtime/api/connection_user.dart 171                       DatabaseConnectionUser.doWhenOpened.<fn>
dart:async/zone.dart 1538                                                    _rootRunUnary
package:spotube/models/database/database.dart 85                             AppDatabase.migration.<fn>
package:spotube/models/database/database.steps.dart 1211                     migrationSteps.<fn>
package:drift/internal/versioned_schema.dart 103                             VersionedSchema.runMigrationSteps
package:drift/internal/versioned_schema.dart 54                              VersionedSchema.stepByStepHelper.<fn>
package:drift/src/runtime/api/db_base.dart 133                               GeneratedDatabase.beforeOpen.<fn>
dart:isolate 297                                                             Isolate.run.<fn>
package:drift/src/remote/communication.dart 165                              DriftCommunication.setRequestHandler.<fn>
===== asynchronous gap ===========================
package:drift/src/remote/communication.dart 113                              DriftCommunication.request
package:drift/src/remote/server_impl.dart 309                                _ServerDbUser.beforeOpen
package:drift/src/runtime/executor/helpers/engines.dart 482                  DelegatedDatabase._runMigrations
package:drift/src/runtime/executor/helpers/engines.dart 446                  DelegatedDatabase.ensureOpen.<fn>
dart:async/future_impl.dart 82                                               _AsyncCompleter.complete
===== asynchronous gap ===========================
package:drift/src/remote/communication.dart 113                              DriftCommunication.request
package:drift/src/remote/client_impl.dart 173                                _RemoteQueryExecutor.ensureOpen
package:drift/src/utils/lazy_database.dart 64                                LazyDatabase.ensureOpen.<fn>
dart:async/zone.dart 1538                                                    _rootRunUnary
package:drift/src/runtime/api/connection_user.dart 169                       DatabaseConnectionUser.doWhenOpened.<fn>
package:drift/src/runtime/query_builder/statements/select/select.dart 90     SimpleSelectStatement._mapResponse
package:drift/src/runtime/query_builder/statements/query.dart 240            Selectable.getSingleOrNull
package:spotube/provider/user_preferences/user_preferences_provider.dart 27  UserPreferencesNotifier.build.<fn>

@tomballgithub
Copy link

I'm leaving this Node.js typescript implementation to generate TOTP for the endpoint. As a lot of projects are facing the same issues. And it'll be easier to read JS compared to Dart. Btw, which ever programming language/library you use for generating TOTP, make sure it supports RFC4226 and RFC6238

In Dart we used , otp_util package which supports both RFCs

import { TOTP } from "totp-generator";

async function main() {

const secretSauce = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
const base32FromBytes = (e: Uint8Array) => {
    let t = 0;
    let n = 0;
    let r = "";
    for (let i = 0; i < e.length; i++) {
        n = n << 8 | e[i];
        t += 8;
        while (t >= 5) {
            r += secretSauce[n >>> t - 5 & 31];
            t -= 5;
        }
    }
    if (t > 0) {
        r += secretSauce[n << 5 - t & 31];
    }
    return r;
}

function cleanBuffer(e: string): Uint8Array<ArrayBuffer> {
    e = e.replace(/ /g, "");
    const t = new ArrayBuffer(e.length / 2);
    const n = new Uint8Array(t);
    for (let r = 0; r < e.length; r += 2) {
        n[r / 2] = parseInt(e.substring(r, r + 2), 16);
    }
    return n;
};

const secretCipherBytes = [12, 56, 76, 33, 88, 44, 88, 33, 78, 78, 11, 66, 22, 22, 55, 69, 54].map((e, t) => e ^ t % 33 + 9)

const secretBytes = new Uint8Array((cleanBuffer(Buffer.from(secretCipherBytes.join(""), "utf8").toString("hex")).buffer));

const secret = base32FromBytes(secretBytes);

const res = await fetch("https://open.spotify.com/server-time").then((e) => e.json())
const timestamp = res["serverTime"];

const totp = TOTP.generate(secret, {
    algorithm: "SHA-1",
    digits: 6,
    period: 30,
    timestamp: timestamp * 1000,
});

const currentTimestamp = Math.floor(Date.now() / 1000);

console.log("secretCipherBytes:", secretCipherBytes);
console.log("secretBytes:", secretBytes);
console.log("secret:", secret);
console.log(`https://open.spotify.com/get_access_token?reason=transport&productType=web_player&totp=${totp.otp}&totpVer=5&ts=${currentTimestamp}`);

}

main();

Do you know of a project that has implemented fully functional node.js code or is working on it? The ones I've seen are Dart and Python, but I need to update a node.js implementation.

@AlexDev404
Copy link

I'm leaving this Node.js typescript implementation to generate TOTP for the endpoint.
As a lot of projects are facing the same issues. And it'll be easier to read JS compared to Dart.
Btw, which ever programming language/library you use for generating TOTP, make sure it supports RFC4226 and RFC6238

In Dart we used , otp_util package which supports both RFCs

import { TOTP } from "totp-generator";

async function main() {

    const secretSauce = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
    const base32FromBytes = (e: Uint8Array) => {
        let t = 0;
        let n = 0;
        let r = "";
        for (let i = 0; i < e.length; i++) {
            n = n << 8 | e[i];
            t += 8;
            while (t >= 5) {
                r += secretSauce[n >>> t - 5 & 31];
                t -= 5;
            }
        }
        if (t > 0) {
            r += secretSauce[n << 5 - t & 31];
        }
        return r;
    }

    function cleanBuffer(e: string): Uint8Array<ArrayBuffer> {
        e = e.replace(/ /g, "");
        const t = new ArrayBuffer(e.length / 2);
        const n = new Uint8Array(t);
        for (let r = 0; r < e.length; r += 2) {
            n[r / 2] = parseInt(e.substring(r, r + 2), 16);
        }
        return n;
    };

    const secretCipherBytes = [12, 56, 76, 33, 88, 44, 88, 33, 78, 78, 11, 66, 22, 22, 55, 69, 54].map((e, t) => e ^ t % 33 + 9)

    const secretBytes = new Uint8Array((cleanBuffer(Buffer.from(secretCipherBytes.join(""), "utf8").toString("hex")).buffer));

    const secret = base32FromBytes(secretBytes);

    const res = await fetch("https://open.spotify.com/server-time").then((e) => e.json())
    const timestamp = res["serverTime"];

    const totp = TOTP.generate(secret, {
        algorithm: "SHA-1",
        digits: 6,
        period: 30,
        timestamp: timestamp * 1000,
    });

    const currentTimestamp = Math.floor(Date.now() / 1000);

    console.log("secretCipherBytes:", secretCipherBytes);
    console.log("secretBytes:", secretBytes);
    console.log("secret:", secret);
    console.log(`https://open.spotify.com/get_access_token?reason=transport&productType=web_player&totp=${totp.otp}&totpVer=5&ts=${currentTimestamp}`);
}

main();

I don't think it was a good idea for you to have posted this here. Because this code here is a bit borderline, and Spotify now has the right to either rotate their secrets, patch the flaw you're exploiting, or take further action.

This was referenced Mar 21, 2025
@KRTirtho KRTirtho marked this as a duplicate of #2572 Mar 23, 2025
@KRTirtho KRTirtho marked this as a duplicate of #2581 Mar 23, 2025
@GeoTsak314
Copy link

It appeared again a while ago today. Still off!

Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working deployed This issue has been fixed/implmented and has been released
Projects
Status: Deployed
Development

No branches or pull requests