rinukkusu / spotify-dart

A dart library for interfacing with the Spotify API.
BSD 3-Clause "New" or "Revised" License
206 stars 93 forks source link

Use in combination with SpotifySdk getAuthenticationToken #70

Closed Pajn closed 2 years ago

Pajn commented 4 years ago

I'm trying to use this library in combination with https://github.com/brim-borium/spotify_sdk. SpotifySdk has a method to get a token from the spotify app but when I use it like this I get 401 when trying to access user data (my playlists in this case):

    FutureBuilder(
      future: SpotifySdk.getAuthenticationToken(
          clientId: '...',
          redirectUrl: 'comspotifytestsdk://callback',
          scope: scopes.join(', ')),
      builder: (context, snapshot) {
        if (snapshot.data == null) {
          return Scaffold(body: Center(child: Text('Not logged in')));
        }

        var credentials = SpotifyApiCredentials(
            '...',
            '...',
            accessToken: snapshot.data,
            scopes: scopes);

        /// ...
      },
    );
roisnir commented 4 years ago

Hi, I don't know how doe's spotify_sdk plugin implements the authentication so I'll need more details to help. Try coping the token you get from SpotifySdk.getAuthenticationToken and using it in Spotify's console Then comment if you got 401 in the console too (if so, token has no permissions to get your playlists data). and which scopes you passed to getAuthenticationToken.

By the way, it looks like you call getAuthenticationToken in the build method which is recommanded as you wish to create the future once (in initState for instance) and then pass the future object to the FutureBuilder

oozkaya commented 3 years ago

Hello,

I kinda have the same issue, using the same library spotify_sdk.

I will be able to get my accessToken with getAuthenticationToken and then pass it in my credentials just like @Pajn, and then get my spotifyApi.

However, using it to get the user's playlists (spotifyApi.playlists.me.all() inside a FutureBuilder) will throw Unhandled Exception: Error Code: 401 Unauthorized.

My scopes were :

List<String> scopes = [
    'app-remote-control',
    'user-modify-playback-state',
    'user-read-private',
    'playlist-read-private',
    'playlist-modify-public',
    "playlist-read-collaborative",
    'user-read-currently-playing',
  ];

Same if I try with playlist-read-private only.

I've tested that same token with Spotify's console, and it worked correctly. My other public API calls like search works perfectly though...

Could you help me please ? 😣

oozkaya commented 3 years ago

Hello again !

I found that the spotify_sdk was using the Authorization Code with PKCE method.

In the end, I tried the normal way of authenticating with the spotify API just like in the Readme. However I had some hard times and found that you must not forget to configure correctly your AndroidManifest.xml (in the case of Android). This link helped me. In my case, I used the same datas as I used for redirectUri in the readme example.

I hope this can help others in the future !

fotiDim commented 3 years ago

Hi all. I am co-maintainer of the spotify_sdk package.

@roisnir the access token that we get from SpotifySdk.getAuthenticationToken() is perfectly usable in the web API. If the user needs additional scopes those can be requested through the SDK.

@oozkaya spotify_sdk is authenticating through the Spotify app. So it is whatever flow they are using. To us (the clients) they are only exposing the access token and nothing else. It is more like the Implicit Grant flow rather than the flow you mention.

I want to use this package in a project and it seems I have to pass client secret in order to reuse my access token from the spotify_sdk. I tried:

SpotifyApiCredentials(
      'MY_CLIENT_ID',
      'DUMMY_CLIENT_SECRET',
      accessToken: 'MY_TOKEN',
    );

but I am getting Unhandled Exception: OAuth authorization error (invalid_client): Invalid client secret. The secret should be optional and in fact it is a security risk having it in the app. Ideally the client ID should also be optional since it is useless in the case that I am passing an already valid access token and token refreshing is not possible.

EDIT: It looks like that the accessToken argument in SpotifyApiCredentials is ignored and that is why it is returning a 401. I would expect all the endpoints that require non default scopes to fail.