librespot-java
                                
                                 librespot-java copied to clipboard
                                
                                    librespot-java copied to clipboard
                            
                            
                            
                        Using all possible token scopes by default for Web API requests breaks specific /web-api/ endpoints, and the /tokens endpoint a long with it
- The spotify web-api breaks with specific combinations of token scopes, see #399
- If you try creating a token through the spotify web console as found in the WebApihandleryou'll get a 'Illegal scope' page
- It appears that there's some scopes that can't be used together in a single token, and upon using that token in the spotify web api, as shown in #399, the spotify api simply returns the json model without any content, instead of an explicit error
- In the current intended design of api, I could just use/tokens/{scope}to request a specific token with just a singular scope, however, because a token is being generated implicitly with ALL possible scopes, the token returned by/tokens/{scope}is the default token generated with all possible scopes, breaking certain/web-api/endpoints, and/tokensitself, becausegetTokenfinds the first available token of the requested scope, which in this case is a token with ALL possible scopes
The only solution that currently exists is to completely avoid using any /web-api/ endpoint without specifying X-Spotify-Scope, upon calling /web-api/ without X-Spotify-Scope, a token for ALL scopes is generated, without a way to force generate a new token
Potential solution
Remove implicit token generation, and require a X-Spotify-Scope or scope in the /token request, no need to tweak the token store. Tokens will still be stored and cached, and the first token with the needed scope will still be retrieved from the token store list. The only difference is users will need to explicitly add a scope to their /web-api/ request. The issue of unsupported combinations of scopes will still remain though, so a key-value map for token storage might be a better solution. /token could take a third optional parameter, it being the key for the token store map. By default the scope could be used as the key in the store
Version/Commit v1.6.1
Thank you for the detailed issue, I'll get to this whenever I'll have time. PRs are appreciated.
Thank you for the detailed issue, I'll get to this whenever I'll have time. PRs are appreciated.
It'd appear that something is off with key generation, using only a single scope when a key is generated internally via
    @NotNull
    public static JsonMercuryRequest<GenericJson> requestToken(@NotNull String deviceId, @NotNull String scope) {
        return new JsonMercuryRequest<>(RawMercuryRequest.get(String.format("hm://keymaster/token/authenticated?scope=%s&client_id=%s&device_id=%s", scope, KEYMASTER_CLIENT_ID, deviceId)), GenericJson.class);
    }
The returned access token doesn't work, the Spotify API gives me the same result as reported, it seems like I was wrong with compatibility between multiple scopes. This appears to be related to the actual token generation.
This appears to be related to the actual token generation.
The API used for token generation is strictly an internal API which happens to work with the Web API sometimes.
This appears to be related to the actual token generation.
The API used for token generation is strictly an internal API which happens to work with the Web API sometimes.
What would be the best route to take? I notice the length of keys generated via the web-console is quite different than the one being generated by librespot-java, is this something I could debug further, or would it be best to lay certain endpoints aside?