使用隐式授权的Spotify身份验证失败

时间:2018-06-20 01:09:17

标签: javascript spotify

我正在尝试使用概述于here的隐式授权流程向Spotify进行身份验证。我已将localhost:3000和localhost:3000 / callback /添加到我的用户开发信息中心(我也尝试了这些的各种组合,例如http://localhost:3000/callback,localhost:3000 / callback,以及几乎所有我能做的怪癖考虑到)。我正在使用this Github页面上的Spotify教程中提供的示例。这是我的隐式授予身份验证的设置:

app.js:

/**                                                                             
 * This is an example of a basic node.js script that performs                   
 * the Implicit Grant oAuth2 flow to authenticate against                       
 * the Spotify Accounts.                                                        
 *                                                                              
 * For more information, read                                                   
 * https://developer.spotify.com/web-api/authorization-guide/#implicit_grant_flow
 */                                                                             

var express = require('express'); // Express web server framework               
var app = express();                                                            
app.use(express.static(__dirname + '/public'));                                 
console.log('Listening on 3000');                                               

app.listen(3000);

index.html:

<!doctype html>
<html>
  <head>
    <title>Example of the Implicit Grant flow with Spotify</title>
    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
    <style type="text/css">
      #login, #loggedin {
        display: hidden;
      }
      .text-overflow {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        width: 500px;
      }
    </style>
  </head>

  <body>
    <div class="container">
      <div id="login">
        <h1>This is an example of the Implicit Grant flow</h1>
        <button id="login-button" class="btn btn-primary">Log in with Spotify</button>
      </div>
      <div id="loggedin">
        <div id="user-profile">
        </div>
        <div id="oauth">
        </div>
      </div>
    </div>

    <script id="user-profile-template" type="text/x-handlebars-template">
      <h1>Logged in as {{display_name}}</h1>
      <div class="media">
        <div class="pull-left">
          <img class="media-object" width="150" src="{{images.0.url}}" />
        </div>
        <div class="media-body">
          <dl class="dl-horizontal">
            <dt>Display name</dt><dd class="clearfix">{{display_name}}</dd>
            <dt>Id</dt><dd>{{id}}</dd>
            <dt>Email</dt><dd>{{email}}</dd>
            <dt>Spotify URI</dt><dd><a href="{{external_urls.spotify}}">{{external_urls.spotify}}</a></dd>
            <dt>Link</dt><dd><a href="{{href}}">{{href}}</a></dd>
            <dt>Profile Image</dt><dd class="clearfix"><a href="{{images.0.url}}">{{images.0.url}}</a></dd>
            <dt>Country</dt><dd>{{country}}</dd>
          </dl>
        </div>
      </div>
    </script>

    <script id="oauth-template" type="text/x-handlebars-template">
      <h2>oAuth info</h2>
      <dl class="dl-horizontal">
        <dt>Access token</dt><dd class="text-overflow">{{access_token}}</dd>
      </dl>
    </script>

    <script src="//cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0-alpha.1/handlebars.min.js"></script>
    <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
    <script>
      (function() {

        var stateKey = 'spotify_auth_state';

        /**
         * Obtains parameters from the hash of the URL
         * @return Object
         */
        function getHashParams() {
          var hashParams = {};
          var e, r = /([^&;=]+)=?([^&;]*)/g,
              q = window.location.hash.substring(1);
          while ( e = r.exec(q)) {
             hashParams[e[1]] = decodeURIComponent(e[2]);
          }
          console.log(hashParams);
          return hashParams;
        }

        /**
         * Generates a random string containing numbers and letters
         * @param  {number} length The length of the string
         * @return {string} The generated string
         */
        function generateRandomString(length) {
          var text = '';
          var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

          for (var i = 0; i < length; i++) {
            text += possible.charAt(Math.floor(Math.random() * possible.length));
          }
          return text;
        };

        var userProfileSource = document.getElementById('user-profile-template').innerHTML,
            userProfileTemplate = Handlebars.compile(userProfileSource),
            userProfilePlaceholder = document.getElementById('user-profile');

            oauthSource = document.getElementById('oauth-template').innerHTML,
            oauthTemplate = Handlebars.compile(oauthSource),
            oauthPlaceholder = document.getElementById('oauth');

        var params = getHashParams();

        var access_token = params.access_token,
            state = params.state,
            storedState = localStorage.getItem(stateKey);

        console.log(access_token);
        if (access_token && (state == null || state !== storedState)) {
          console.log('reached null state or unstored state');
          alert('There was an error during the authentication');
        } else {
          localStorage.removeItem(stateKey);
          if (access_token) {
            $.ajax({
                url: 'https://api.spotify.com/v1/me',
                headers: {
                  'Authorization': 'Bearer ' + access_token
                },
                success: function(response) {
                  userProfilePlaceholder.innerHTML = userProfileTemplate(response);

                  $('#login').hide();
                  $('#loggedin').show();
                }
            });
          } else {
              console.log('Second Canary');
              $('#login').show();
              $('#loggedin').hide();
          }

          document.getElementById('login-button').addEventListener('click', function() {

            var client_id = 'Not for your eyes'; // Your client id
            var redirect_uri = 'localhost:3000/callback/'; // Your redirect uri

            var state = generateRandomString(16);

            localStorage.setItem(stateKey, state);
            var scope = 'user-read-private user-read-email';

            var url = 'https://accounts.spotify.com/authorize';
            url += '?response_type=token';
            url += '&client_id=' + encodeURIComponent(client_id);
            url += '&scope=' + encodeURIComponent(scope);
            url += '&redirect_uri=' + encodeURIComponent(redirect_uri);
            url += '&state=' + encodeURIComponent(state);
            url += '&show_dialog=true';

            console.log(url);
            window.location = url;
            console.log('clicked');
          }, false);
        }
      })();
    </script>
</html>

批准我的申请后,我无济于事地返回URI。结果如下: Firefox Error

换句话说,我正在得到应有的回应(至少在我看来如此)。但是Firefox不知道该怎么做,Chrome希望我使用xdg-open。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我现在正在执行此流程。首先,我在仪表板上更改了URL。现在,我将它们设置为http://localhost:3000http://localhost:3000/callback。然后,我在app.js文件中添加了一条路由:

app.get('/callback', function(req, res) {
   res.redirect('/');
});

这解决了我的问题,现在我可以正确地进行身份验证了。