Почему Heroku работает только тогда, когда я также запускаю узел app.js локально?

#node.js #heroku #spotify

#node.js #heroku #spotify

Вопрос:

У меня есть приложение, которое я создал с помощью Node.js и API Spotify. Когда я запускаю приложение локально в VS Code, оно работает, перейдя на localhost: 8888. Однако после того, как я развернул его на heroku, я получаю сообщение об ошибке при попытке щелкнуть логин Spotify со словами «Сайт недоступен», localhost отказался подключаться. Ссылка на веб-сайт vtraxx.herokuapp.com и я опубликую некоторые из соответствующих кодов ниже:

РЕДАКТИРОВАТЬ: я изменил перенаправление на: https://vtraxx.herokuapp.com/callback и теперь ничего не происходит, когда вы нажимаете «Войти в Spotify». Я также забыл отредактировать перенаправление в моем config.js файл, но после этого все равно ничего не происходит

РЕДАКТИРОВАНИЕ 2: я смог заставить логин работать, изменив перенаправление на:vtraxx.herokuapp.com/login . Однако теперь я получаю сообщение об ошибке, что перенаправлений слишком много. Я очистил свои файлы cookie в первый раз, и это должно было сработать, но в конечном итоге этого не произошло.

app.js:

 const request = require('request'); // "Request" library
const cors = require('cors');
const querystring = require('querystring');
const cookieParser = require('cookie-parser');
const { config } = require('./config');

var client_id = 'client id'; // Your client id
var client_secret = 'client secret'; // Your secret
var redirect_uri = 'http://localhost:8888/callback'; // Your redirect uri

/**
 * Generates a random string containing numbers and letters
 * @param  {number} length The length of the string
 * @return {string} The generated string
 */
var generateRandomString = function (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 stateKey = 'spotify_auth_state';

var app = express();

app.use(express.static(__dirname   '/public'))
    .use(cors())
    .use(cookieParser());

app.get('/login', function (req, res) {
    var state = generateRandomString(16);
    res.cookie(stateKey, state);

    // your application requests authorization
    var scope = 'user-read-private user-read-email user-top-read';
    res.redirect(
        'https://accounts.spotify.com/authorize?'  
            querystring.stringify({
                response_type: 'code',
                client_id: client_id,
                scope: scope,
                redirect_uri: redirect_uri,
                state: state
            })
    );
});

app.get('/callback', function (req, res) {
    // your application requests refresh and access tokens
    // after checking the state parameter

    var code = req.query.code || null;
    var state = req.query.state || null;
    var storedState = req.cookies ? req.cookies[stateKey] : null;

    if (state === null || state !== storedState) {
        res.redirect(
            '/#'  
                querystring.stringify({
                    error: 'state_mismatch'
                })
        );
    } else {
        res.clearCookie(stateKey);
        var authOptions = {
            url: 'https://accounts.spotify.com/api/token',
            form: {
                code: code,
                redirect_uri: redirect_uri,
                grant_type: 'authorization_code'
            },
            headers: {
                Authorization: 'Basic '   new Buffer(client_id   ':'   client_secret).toString('base64')
            },
            json: true
        };

        request.post(authOptions, function (error, response, body) {
            if (!error amp;amp; response.statusCode === 200) {
                var access_token = body.access_token,
                    refresh_token = body.refresh_token;

                var options = {
                    url: 'https://api.spotify.com/v1/me',
                    headers: { Authorization: 'Bearer '   access_token },
                    json: true
                };

                var topOptions = {
                    url: 'https://api.spotify.com/v1/me/top/tracks',
                    headers: { Authorization: 'Bearer '   access_token },
                    json: true
                };

                // use the access token to access the Spotify Web API
                request.get(topOptions, function (error, response, body) {
                    for (let i = 0; i < body.items.length; i  ) {
                        console.log(body);
                    }
                });

                // we can also pass the token to the browser to make requests from there
                res.redirect(
                    '/#'  
                        querystring.stringify({
                            access_token: access_token,
                            refresh_token: refresh_token
                        })
                );
            } else {
                res.redirect(
                    '/#'  
                        querystring.stringify({
                            error: 'invalid_token'
                        })
                );
            }
        });
    }
});

app.get('/refresh_token', function (req, res) {
    // requesting access token from refresh token
    var refresh_token = req.query.refresh_token;
    var authOptions = {
        url: 'https://accounts.spotify.com/api/token',
        headers: { Authorization: 'Basic '   new Buffer(client_id   ':'   client_secret).toString('base64') },
        form: {
            grant_type: 'refresh_token',
            refresh_token: refresh_token
        },
        json: true
    };

    request.post(authOptions, function (error, response, body) {
        if (!error amp;amp; response.statusCode === 200) {
            var access_token = body.access_token;
            res.send({
                access_token: access_token
            });
        }
    });
});

app.listen(process.env.PORT || 8888, function () {
    console.log('Server is running on port 8888');
});```

I put the localhost:8888 in the spotify dashboard as well. This is my very first project and I'm not exactly sure I know what I'm doing but this is the final step to the finish product and I'm pulling my hair out. This is also my first time using node.js/JavaScript in general
  

Комментарии:

1. Потому что ваш URI перенаправления все еще находится на localhost.

2. Должен ли Heroku предоставить мне новый URI? Прошу прощения, если мой вопрос является основным, я новичок во всем этом. На что мне заменить localhost:8888?

3. Spotify перенаправит ваш клиент обратно туда, куда вы ему указали (вероятно, в некоторых пределах). На данный момент вы говорите ему перенаправить их на localhost — это работает на вашей машине (когда она запущена локально), но не будет работать ни на чьей другой. Итак, вам нужна конфигурация , чтобы отправлять их на маршрут обратного вызова вашего приложения Heroku в prod.

4. Я смог исправить эту проблему, но теперь, когда вы нажимаете кнопку входа в систему, я получаю сообщение об ошибке: слишком много перенаправлений

Ответ №1:

Ваше развертывание Heroku просит Spotify перенаправить браузер обратно localhost . Вот почему он запускается только тогда, когда ваше приложение запущено локально.

Когда ваше приложение работает локально, а Spotify перенаправляет ваш браузер localhost , ваш браузер подключается к вашему локальному компьютеру через порт 8888.

Когда ваше приложение запущено в Heroku, а Spotify перенаправляет ваш браузер localhost , ваш браузер подключается к вашему локальному компьютеру через порт 8888. Это не возвращает вас к Heroku.

Измените redirect_uri так, чтобы он отражал экземпляр Heroku ( herokuapp.com URL) вместо localhost .

Комментарии:

1. Однако это имеет гораздо больше смысла (и, пожалуйста, простите меня), если я изменю URL перенаправления на vtraxx.herokuapp.com ничего не произойдет, потому что это просто перенаправление обратно на главную страницу. Я ценю помощь, хотя я почти на месте!

2. Вы перенаправляете на /callback маршрут или просто на главную страницу?

3. Я перенаправляю на vtraxx.herokuapp.com/callback . Я предполагаю, что мне также нужно сделать то же самое на панели управления Spotify

4. Все вызовы перенаправления в вашей callback функции идут /# (вместе с некоторыми параметрами GET). Это отправит вас обратно на ваш / маршрут, который является вашей главной страницей.

5. Я смог заставить это работать, но теперь я получаю сообщение об ошибке, что в Spotify слишком много перенаправлений