Express -сессия не сохраняет заданные переменные после запроса на стороне сервера ajax (для подмены API) с использованием модуля запроса - PullRequest
2 голосов
/ 13 апреля 2020

Я пытаюсь создать веб-сайт для организации музыки c на основе жанров, и поэтому мне нужно использовать API spotify. Я разрешаю и устанавливаю session.loggedIn и другие переменные на нужные переменные. Но эти переменные не сохраняются после их установки. Ниже приведен наиболее важный код (также включен полный код чуть ниже). После входа пользователь отправляется после посещения страницы входа в систему и перенаправления.

request.post(clientServerOptions, (err, postres, body) => onReplyToAuth(req,res,err,postres,body)) затем вызывает POST-аутентификацию с сервера, чтобы получить ключ для доступа к данным. Все соединение успешно, данные, полученные в теле, являются правильными данными (подтвердил это).

{
  if(req.session.loggedIn) res.redirect(res.locals.pathPrefix+"/listofplaylists");
  else if(true)
  {
    var code = req.query.code
    if(!code) res.redirect(res.locals.pathPrefix);
    else
    {
      req.session.authCode = code;
      var clientServerOptions = 
      {
        url: "https://accounts.spotify.com/api/token",
        form: 
        {
          grant_type : "authorization_code",
          code: code,
          redirect_uri:"http://www.localhost:8080"+res.locals.pathPrefix+"/afterSignIn"
        },
        headers:
        {
          'Authorization' : 'Basic ' + (new Buffer(myClientId+":"+myClientSecret).toString("base64"))
        },
        json: true
      };
      request.post(clientServerOptions, (err, postres, body) => onReplyToAuth(req,res,err,postres,body));
    }

  }
  else
  {
    res.redirect(res.locals.pathPrefix);
  }
});

function onReplyToAuth(req,res,err,postres,body)
{
  console.log(body);
  if(!err)
  {
    req.session.loggedIn = true;
    req.session.loggingIn = false;
    req.session.accessToken = body.access_token;
    req.session.refreshToken = body.refresh_token;  
    console.log("Before saving:");
    console.log(req.session);
    req.session.save(function(err) 
    {
      if(!err)
      {
        console.log("After saving:")
        console.log(req.session);
        res.redirect(res.locals.pathPrefix+"/listofplaylists");
      }
    });

  }
  else
  {
    res.redirect(res.locals.pathPrefix);
  }
}

Использование router.use((req,res,next)=>{console.log(req.session);next()}); Я заметил, что req.session.x не определен для всех установленных переменных, когда в новый запрос. Кроме того, я проверил выполнение кода (используя консольный журнал после назначений, сеанс и переменные были доступны (req.session был правильно установлен там).

FULL SOURCE:

var request = require('request');
var createError = require('http-errors');
var path = require('path');
var cookieParser = require('cookie-parser');
var router = express.Router();
var session = require("express-session")({secret: 'cookie secret',
resave: false,
saveUninitialized: true,
cookie: { secure: true }});
var myClientId = "my id";
var myClientSecret = "my secret"

router.use(session)
router.use((req,res,next)=>{console.log(req.session);next()});

router.get("/requestsignin", function(req,res,next)
{
  var scopes="playlist-read-collaborative playlist-modify-public playlist-read-private playlist-modify-private";
  res.redirect('https://accounts.spotify.com/authorize' +
  '?response_type=code' +
  '&client_id=' + myClientId +
  (scopes ? '&scope=' + encodeURIComponent(scopes) : '') +  
  '&redirect_uri=' + encodeURIComponent("http://www.localhost:8080"+res.locals.pathPrefix+"/afterSignIn"));
});

router.get("/afterSignIn", function(req, res)
{
  if(req.session.loggedIn) res.redirect(res.locals.pathPrefix+"/listofplaylists");
  else if(true)
  {
    var code = req.query.code
    if(!code) res.redirect(res.locals.pathPrefix);
    else
    {
      req.session.authCode = code;
      var clientServerOptions = 
      {
        url: "https://accounts.spotify.com/api/token",
        form: 
        {
          grant_type : "authorization_code",
          code: code,
          redirect_uri:"http://www.localhost:8080"+res.locals.pathPrefix+"/afterSignIn"
        },
        headers:
        {
          'Authorization' : 'Basic ' + (new Buffer(myClientId+":"+myClientSecret).toString("base64"))
        },
        json: true
      };
      request.post(clientServerOptions, (err, postres, body) => onReplyToAuth(req,res,err,postres,body));
    }

  }
  else
  {
    res.redirect(res.locals.pathPrefix);
  }
});


function onReplyToAuth(req,res,err,postres,body)
{
  if(!err)
  {
    req.session.loggedIn = true;
    req.session.loggingIn = false;
    req.session.accessToken = body.access_token;
    req.session.refreshToken = body.refresh_token;  
    res.redirect(res.locals.pathPrefix+"/listofplaylists");
  }
  else
  {
    res.redirect(res.locals.pathPrefix);
  }
}

function requestSpotifyData(url,req, callback)
{
  var authOptions = 
  {
    url:url,
    headers:
    {
      'Authorization':"Bearer " + req.session.accessToken
    },
    json : true
  }
  request.get(authOptions,callback);
}

router.get("/listofplaylists", function(req,res,next)
{
  if(!req.session.loggedIn)
  {
    res.redirect(res.locals.pathPrefix)
  }
  else
  {
    requestSpotifyData("https://api.spotify.com/v1/me/playlists?limit=50",req,(err,postres,body) =>
    {
      res.render("listOfplaylists",
      {
        playlists : body.items
      });
    });
  }

});



/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});




module.exports = router;

Приложение Nodemon. js debug (обратите внимание, что код запускается до журнала get (приведенный выше код соответствует запросу):

Session {
  cookie: {
    path: '/',
    _expires: null,
    originalMaxAge: null,
    httpOnly: true,
    secure: true
  }
}
GET /spotify/requestsignin 302 18.590 ms - 628
Session {
  cookie: {
    path: '/',
    _expires: null,
    originalMaxAge: null,
    httpOnly: true,
    secure: true
  }
}
(node:1596) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
{
  access_token: 'access token',
  token_type: 'Bearer',
  expires_in: 3600,
  refresh_token: 'refresh token',
  scope: 'playlist-read-private playlist-read-collaborative playlist-modify-private playlist-modify-public'
}
Before saving:
Session {
  cookie: {
    path: '/',
    _expires: null,
    originalMaxAge: null,
    httpOnly: true,
    secure: true
  },
  authCode: 'auth code',
  loggedIn: true,
  loggingIn: false,
  accessToken: 'access token',
  refreshToken: 'refresh token'
}
After saving:
Session {
  cookie: {
    path: '/',
    _expires: null,
    originalMaxAge: null,
    httpOnly: true,
    secure: true
  },
  authCode: 'auth code',
  loggedIn: true,
  loggingIn: false,
  accessToken: 'access token',
  refreshToken: 'refresh token'
}
GET /spotify/afterSignIn?code=auth code 302 141.181 ms - 92
Session {
  cookie: {
    path: '/',
    _expires: null,
    originalMaxAge: null,
    httpOnly: true,
    secure: true
  }
}
GET /spotify/listofplaylists 302 6.726 ms - 60
Session {
  cookie: {
    path: '/',
    _expires: null,
    originalMaxAge: null,
    httpOnly: true,
    secure: true
  }
}
GET /spotify/ 304 238.770 ms - -
GET /spotify/stylesheets/style.css 304 1.629 ms - -
Session {
  cookie: {
    path: '/',
    _expires: null,
    originalMaxAge: null,
    httpOnly: true,
    secure: true
  }
}
GET /spotify/ 304 15.980 ms - -

Спасибо за помощь!

Ответы [ 2 ]

0 голосов
/ 14 апреля 2020

Когда я бездельничал с настройками сеанса, я изменил

var session = require("express-session")({secret: 'secret`376712',
resave: false,
saveUninitialized: true,
cookie: { secure: true}});

на

var session = require("express-session")({secret: 'secret`376712',
resave: false,
saveUninitialized: true,
cookie: { secure: false }});

и получил список воспроизведения с желаемыми выходами (сеанс больше не сбрасывался) , Я думаю, что это исправление, потому что соединение с сервером - HTTP, а не HTTPS, и поэтому cook ie не отправляется. Я, однако, не уверен в этом.

Большое спасибо другим, которые думают со мной!

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

0 голосов
/ 13 апреля 2020

Я не уверен, что это может быть проблемой, но есть вероятность, что res.redirect был вызван до того, как сеанс был полностью сохранен в функции onReplyToAuth, вы можете попробовать вызвать req.session.save и затем передать функция обратного вызова для перенаправления после сохранения сеанса.

req.session.loggedIn = true;
req.session.loggingIn = false;
req.session.accessToken = body.access_token;
req.session.refreshToken = body.refresh_token;  
req.session.save(function(err) {
  // session saved
  res.redirect(res.locals.pathPrefix+"/listofplaylists");
})

Надеюсь, это поможет.

...