【问题标题】:Express Js/AngularJS cookie session lostExpress Js/AngularJS cookie 会话丢失
【发布时间】:2015-12-07 22:30:54
【问题描述】:

我是新来表达的,我正在尝试在会话中保存一些数据,然后在另一个查询中检索它。我的客户端应用是 AngularJS 应用。

    var express = require('express');
    var path = require('path');
    var favicon = require('serve-favicon');
    var logger = require('morgan');
    var cookieParser = require('cookie-parser');
    var bodyParser = require('body-parser');
    var cookieSession = require('cookie-session');
    app.use(cookieParser());
    app.use(cookieSession({
      name: 'session',
      keys: ['mySecret']
    }));
    app.use(bodyParser.json());

检索会话时,它始终是一个空对象 {} 可能是什么原因? 谢谢!

编辑

这是我现在的 app.js

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
//var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var cookieSession = require('cookie-session');
var methodOverride = require('method-override');

var session = require('express-session');

//Services
var routes = require('./routes/index');
var users = require('./routes/users');
var typesOperateurs = require('./routes/typesOperateurs');
var domains = require('./routes/domains');
var categories = require('./routes/categories');
var donnees = require('./routes/donnees');
var arcepData = require('./routes/arcepData');
var generalData = require('./routes/generalData');

var app = express();

var properties = require('./configs/properties');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
//app.use(cookieParser('arcepSecret'));
/*app.use(cookieSession({
      name: 'session',
      keys: ['arcepSecret'],
          httpOnly : false
    }));*/
app.use(session({
    secret:'arcepSecret',
    resave: true,
    saveUninitialized: true,
    name : 'arcep.sid'
}));
app.use(bodyParser.json());
app.use(function (req, res, next) {

    // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', properties.clientHost);

    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);

    // Pass to next layer of middleware
    next();
});
//app.use(methodOverride);

//app.use(express.static(path.join(__dirname, 'public')));

//storing models
app.use(function(req, res, next) {  
      req.models = app.models;  
      next();
    });

// Routes
app.use('/arcep', routes);
app.use('/arcep/users', users);
app.use('/arcep/typesOperateurs', typesOperateurs);
app.use('/arcep/domains', domains);
app.use('/arcep/categories', categories);
app.use('/arcep/donnees', donnees);
app.use('/arcep/arcep_data', arcepData);
app.use('/arcep/general_data', generalData);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});



module.exports = app;

我正在里面填充会话

router.post('/link1', function (req, res, next) {
  req.session.name = 'khalil';
});

我正试图在里面检索它

router.post('/link2', function (req, res, next) {
        console.log(req.session);
})

EDIT2

我发现如果直接从浏览器调用服务,一切都很好,但是当从客户端应用程序(托管在 tomcat 服务器上的 angular 应用程序)尝试时,就会出现问题。

【问题讨论】:

  • 解决方案是在 Angular 应用程序中允许凭据,link

标签: angularjs node.js session express cookies


【解决方案1】:

解决方案是在 Angular 应用中允许凭据。

.config(function ($routeProvider, $httpProvider) {
    $httpProvider.defaults.withCredentials = true;

$http doesn't send cookie in Requests

【讨论】:

    【解决方案2】:

    我建议你导入express-session (https://github.com/expressjs/session)。

    试试这个:

    var expressSession = require('express-session');
    
    app.use(expressSession({secret:'somesecrettokenhere'}));
    

    设置获取会话中的值:

    app.get('/', function(req, res) {
      req.session.hello_message = "Hello world";
      res.send(req.session.hello_message);
    });
    

    会话变量hello_message 将在应用程序的任何地方都可用。

    遵循完整示例。

    1) 在app.js的同级创建名为confi.json的文件:

    {
        "SECRET": "Test",
        "KEY": "test.sid",
        "MAX_AGE": {
          "maxAge": 3600000
        }
      }
    

    2) 为此更改app.js

    var express = require('express')
      , cfg = require('./config.json')
      , load = require('express-load')
      , bodyParser = require('body-parser')
      , compression = require('compression')
      , methodOverride = require('method-override')
      , expressSession = require('express-session')
      , cookieParser = require('cookie-parser')
      , app = express()
      , cookie = cookieParser(cfg.SECRET);
    
    app.use(compression());
    app.use(cookie);
    
    app.use(expressSession({
      secret: cfg.SECRET, 
      name: cfg.KEY, 
      resave: false, 
      saveUninitialized: false,
    
    }));
    
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({extended: true}));
    app.use(methodOverride('_method'));
    
    app.get('/', function(req, res) {
      req.session.hello_message = "Hello world";
      console.log(req.session.hello_message);
    });
    
    app.listen(5000, function(){
      console.log("Test running");
    });
    
    module.exports = app;
    

    3) 更新 package.js:

    {
      "name": "test",
      "version": "0.0.1",
      "description": "test",
      "private": true,
      "scripts": {
        "start": "node app.js"
      },
      "dependencies": {
        "body-parser": "~1.12.0",
        "cookie-parser": "~1.3.4",
        "debug": "~2.1.1",
        "ejs": "~2.3.1",
        "express": "~4.12.2",
        "express-load": "1.1.8",
        "morgan": "~1.5.1",
        "serve-favicon": "~2.2.0"
      }
    }
    

    4) 运行npm update --save 以保存依赖项。

    5) 打开浏览器:localhost:5000,消息应该出现在控制台中。

    【讨论】:

    • 我试过了,但问题仍然存在,会话包含带有键“cookie”的 un 对象,其中包含会话参数、路径、_expires、sessionMaxAge ...
    • 如果我调用另一个服务,req.session.hello_message 是否可以访问,例如如果尝试获取/someService,session.hello_message 的值是否会被保留?
    • 是的,保存在应用程序的任何地方。试试看!
    • 同样的问题,实际上我必须服务 /validate 和 /import,会话在第一个被调用时填充,第二个尝试从会话中检索数据,但它总是空的。跨度>
    • 如果您能提供更多相关信息(app.js 内容、路由、控制器等)...
    【解决方案3】:

    the answer to a related SO question 中所述,如果您使用fetch 从服务器获取数据但未传入credentials 选项,则会发生这种情况:

    fetch('/link2', {
        method: 'POST',
        credentials: 'same-origin' // <- this is mandatory to deal with cookies
    })
    

    除非您包含此选项,否则 Cookie 不会传递到服务器。

    【讨论】:

    • 这是一个如此神秘的错误。你的回答拯救了我的一天。谢谢!
    猜你喜欢
    • 2018-01-23
    • 1970-01-01
    • 2018-07-02
    • 2020-05-02
    • 2012-02-22
    • 2011-01-13
    • 1970-01-01
    • 2016-04-16
    • 2021-08-26
    相关资源
    最近更新 更多