在Express中AngularJS作为前端时未定义会话

我用NodeJS和Express编写了webservice。 服务在端口8090上运行。我还在AngularJS上写了前端,并在端口8080上运行。

Mongo有所有用户的用户名和密码

当我通过HTML5 / AngularJS前端login时,AngularJS应用程序又调用express的http post请求。 用户通过身份validation。 我设置req.session.email =用户的电子邮件地址。

我甚至能够返回并检查在AngularJS的控制台日志req.session.email被设置正确的快递

问题是我在Express中创build了一个名为“restrict”的authentication函数,只有当req.session.email没有被定义时,它才能作为中间件函数来访问其他的get / post请求。

但是即使已经设置了会话,当这个Express的其他get / post请求被AngularJS应用调用时,这个“restrict”函数也会阻止这个调用,因为它接收到req.session.email为undefined

AngularJS和Express都在同一台机器上。 但我不认为这是问题。

Express代码片段

var url = 'mongodb://127.0.0.1:5555/contacts?maxPoolSize=2'; var mongojs = require('mongojs'); var db = mongojs(url,['data']); var dbauth = mongojs(url,['users']); // var request = require('request'); var http = require('http'); var express = require('express'); var cookieparser = require('cookie-parser'); var app = express(); var bodyParser = require('body-parser'); var session = require('express-session'); app.use(cookieparser()); app.use(session({secret:'v3ryc0mpl!c@t3dk3y', resave: false, saveUninitialized: true})); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: true})); var user_session; app.all('*',function(req, res, next){ res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS'); res.header('Access-Control-Allow-Headers', 'Content-Type'); next(); }); function restrict(req,res,next){ try{ if(req.session.email){ next(); } else{ res.send('failed'); res.end(); } } catch(err){ res.send('failed'); res.end(); } }; app.post('/login',function(req,res){ //removed DB function from here to make the code look simple req.session.email = req.body.email; req.session.password = req.body.password; }); app.get('/loggedin',restrict,function(req,res){ res.send(true); }); 

AngularJS调用Express函数来检查会话状态的函数

 var resolveFactory = function ($q, $http, $location,LoginDetails) { var deferred = $q.defer(); $http.get("http://127.0.0.1:8090/loggedin") .success(function (response) { if(response == true){ deferred.resolve(true); } else { deferred.reject(); LoginDetails.setemail(''); LoginDetails.setpassword(''); $location.path("/"); } }) .error(function (err) { deferred.reject(); $location.path("/"); }); return deferred.promise; }; 

从根本上说,我创build的AngularJS Resolve Function应该是成功的,但事实并非如此。 这是失败的。 我正在使用live-server在我的笔记本电脑上运行HTML / AngularJS,并使用nodemon运行Express应用程序

好! 所以原因是AngularJS运行在不同的8080端口上

Express是在8090端口上运行的。这意味着如果AngularJS调用Express的API,除非Express允许将会话传递给AngularJS,而AngularJS使用{withCredentials: true}参数设置Express来调用Express的API 。 下面是AngularJS和ExpressJS在不同端口上运行时必须进行的更改

在AngularJS中确保你调用Express的任何API,它应该像这样{withCredentials: true}

 $http.get('http://expressdomainname:expressport/api',{withCredentials: true}) 

像明智的情况下使用$ http.post参数{withCredentials:true}是重要的

现在在快车方面

确保你有这样的应用程序设置

 app.all('*',function(req, res, next){ //Origin is the HTML/AngularJS domain from where the ExpressJS API would be called res.header('Access-Control-Allow-Origin', 'http://localhost:8080'); res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS'); res.header('Access-Control-Allow-Headers', 'Content-Type'); //make sure you set this parameter and make it true so that AngularJS and Express are able to exchange session values between each other res.header("Access-Control-Allow-Credentials", "true"); next(); }); 

请随时问我,如果你有关于这个话题。 我花了几天时间来解决这个问题