获取适用于 Android 应用的 Spotify API 的访问令牌

Posted

技术标签:

【中文标题】获取适用于 Android 应用的 Spotify API 的访问令牌【英文标题】:Get access token for Spotify API for Android app 【发布时间】:2021-12-22 07:43:13 【问题描述】:

我正在尝试使用以下内容访问 spotify 令牌

OkHttpClient client = new OkHttpClient();

        String state = "azertyuiopmlkjhg";//TODO random string
        String scope = "user-read-private user-read-email";

        URIBuilder ub = new URIBuilder("https://accounts.spotify.com/authorize?")
                .addParameter("client_id", CLIENT_ID)
                .addParameter("response_type", "token")
                .addParameter("scope", scope)
                .addParameter("redirect_uri", REDIRECT_URI)
                .addParameter("state", state);
        String url = ub.toString();
        System.out.println(url);

        Request request = new Request.Builder()
                .header("Content-Type", "application/json")
                .url(url)
                .build();
        client.newCall(request).enqueue(new Callback() 
            @Override
            public void onFailure(Call call, IOException e) 
                e.printStackTrace();
            
            @Override
            public void onResponse(Call call, Response response) throws IOException 
                final String myResponse = response.body().string();
                final String networkResponse = response.networkResponse().request().url().toString();
                System.out.println(myResponse);
                System.out.println(networkResponse);
                if (response.isSuccessful()) 
                    MainActivity.this.runOnUiThread(new Runnable() 
                        @Override
                        public void run() 
                            textView.setText("Success \n"+myResponse);
                        
                    );
                
            
        );

生成的 URL https://accounts.spotify.com/authorize?client_id=e...0&response_type=token&scope=user-read-private+user-read-email&redirect_uri=https%3A%2F%2Faccounts.spotify.com%2Fauthorize&state=azertyuiopmlkjhg 重定向到包含我想要的令牌的链接 https://accounts.spotify.com/authorize#access_token=B...g&token_type=Bearer&expires_in=3600&state=azertyuiopmlkjhg

查询返回应该是:access_token;令牌类型; expires_in 和状态 但我得到了一些 html 作为响应

<html id="app" lang="fr" dir="ltr" ng-csp ng-strict-di>
    <head>
      <meta charset="utf-8">
      <title ng-bind="(&#39;loginTitle&#39; | localize) + &#39; - Spotify&#39;">Spotify</title>
      <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
      <base href="/">
      <link rel="icon" href="https://accounts.scdn.co/sso/images/favicon.ace4d8543bbb017893402a1e9d1ac1fa.ico">
      <link href="https://accounts.scdn.co/sso/css/index.daf98bb304f1ca0e3987.css" media="screen" rel="stylesheet">
      <script defer src="https://accounts.scdn.co/sso/js/index.daf98bb304f1ca0e3987.js" sp-bootstrap></script>
      <meta ng-non-bindable sp-bootstrap-data='"phoneFeatureEnabled":false,"previewEnabled":false,"user":false,"tpaState":"AQ...Q=","BON":["0","0",136907053]'>
    </head>
    <body ng-controller="LoginController">
      <div ng-include="template"></div>
    </body>
    </html>

【问题讨论】:

GET 请求重定向到一个 spotify 登录屏幕,它应该呈现在例如浏览器。只有在用户确认允许应用使用请求的信息后,才会向您的回调 url 发送一个令牌。 【参考方案1】:

这是一个用于 spotify 的示例身份验证流程

https://github.com/yschimke/okurl/blob/0abaa8510dd5466d5e9a08ebe33a009c491749bf/src/main/kotlin/com/baulsupp/okurl/services/spotify/SpotifyAuthFlow.kt

      val scopesString = URLEncoder.encode(scopes.joinToString(" "), "UTF-8")

      val loginUrl =
        "https://accounts.spotify.com/authorize?client_id=$clientId&response_type=code&state=x&redirect_uri=$s.redirectUri&scope=$scopesString"

      outputHandler.openLink(loginUrl)

      val code = s.waitForCode()

      val tokenUrl = "https://accounts.spotify.com/api/token"
      val body = FormBody.Builder().add("client_id", clientId)
        .add("redirect_uri", s.redirectUri)
        .add("code", code)
        .add("grant_type", "authorization_code")
        .build()
      val request = Request.Builder().header(
        "Authorization",
        Credentials.basic(clientId, clientSecret)
      )
        .url(tokenUrl)
        .method("POST", body)
        .build()

      val responseMap = client.queryMap<Any>(request)

      return Oauth2Token(
        responseMap["access_token"] as String,
        responseMap["refresh_token"] as String, clientId, clientSecret
      )
$ okurl --authorize=spotify
Accounts: https://developer.spotify.com/my-applications/
Spotify Client Id []: xxx
Spotify Client Secret []:
Scopes [playlist-read-private,playlist-read-collaborative,playlist-modify-public,playlist-modify-private,streaming,ugc-image-upload,user-follow-modify,user-follow-read,user-library-read,user-library-modify,user-read-private,user-read-birthdate,user-read-email,user-top-read]:

【讨论】:

感谢您的回答,不幸的是,该示例在 Kotlin 中,我无法在 Java 中使用它来响应我的问题。【参考方案2】:

我最终关注了 following tutorial 并使用 spotify 身份验证服务

请注意,AuthenticationRequest 和 AuthenticationClient 现在称为 AuthorizationRequest 和 AuthorizationClient

【讨论】:

以上是关于获取适用于 Android 应用的 Spotify API 的访问令牌的主要内容,如果未能解决你的问题,请参考以下文章

如何让 Spotify 和其他 Android 音乐应用根据意图进行搜索和播放?

使用 Spotify API 的 Android 应用程序仅在调试模式下工作

在 android 上的 spotify 中查找正在播放的歌曲

适用于 ios 的 Spotify API:从 ios spotify api 下载、保存、访问曲目

使用android sdk登录spotify时如何获取帐户类型

通过 Spotify API 在 skipToNext() 方法中使用回调