Express session cookie not persisting after CORS calls
我正在使用Express在端口localhost:3005上运行Node.JS服务器。我在AngularJS中开发了一个客户端,运行在localhost:5000端口上。
我设置了护照身份验证。当我通过控制台或邮递员尝试使用curl命令时,一切正常。
我正在调用"/ login"路由(post),然后"/ authrequired"以知道用户是否经过身份验证。由于存储在客户端的会话cookie,服务器可以识别用户。一切正常。
实际上,每次我调用服务器时,都会使用相同的会话ID来识别用户。例如:84e3ff8a-b237-4899-aa1f-4a3d047e0c3f。
但是,当我使用我的Web客户端应用程序尝试相同的路由时,它不起作用。每次调用服务器时,都会定义一个新的会话ID。
这是标头请求:
1 2 3 4 5 6 7 8 9 10 | Host: 127.0.0.1:3005 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0 Accept: application/json, text/plain, */* Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Referer: http://localhost:5000/ Content-Type: application/json;charset=utf-8 Content-Length: 33 Origin: http://localhost:5000 Connection: keep-alive |
这是回应:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | HTTP/1.1 200 OK X-DNS-Prefetch-Control: off X-Frame-Options: SAMEORIGIN Strict-Transport-Security: max-age=15552000; includeSubDomains X-Download-Options: noopen X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 Content-Length: 76 ETag: W/"4c-UHE7wFwyy1/IvgicFsT1YzsRJZ4" set-cookie: connect.sid=s%3A91e84b8a-63d2-4f01-b28b-882ce1cf1dd5.iIGDvmpU326AF34uAXg%2Bmy1ee28BUGw8TXrFBG0ogKc; Path=/; Expires=Fri, 28 Dec 2018 18:30:50 GMT Date: Thu, 27 Dec 2018 18:30:50 GMT Connection: keep-alive |
我们可以看到,存在一个set-cookie标头。但是当我查看浏览器的cookie存储时,它就不存在了。我认为这就是服务器无法识别客户端的原因,因为客户端不会将会话cookie发送到服务器。
这是我的服务器配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.json()) app.use(cors()) app.use(express.static('data/images')) app.use(cookieParser()) app.use(session({ genid: (req) => { return uuid() }, store: new FileStore(), secret: 'test', resave: false, saveUninitialized: false, cookie: { secure: false, httpOnly: false, path: '/', maxAge: 1000 * 60 * 60 * 24 } })) app.use(passport.initialize()) app.use(passport.session()) |
这是我的客户方要求:
1 2 3 4 5 6 | $http.post(self.url + '/login', { idUser: $scope.name, password: $scope.password }, { // withCredentials: true }) |
我还将这两行配置添加到我的客户端应用程序:
1 2 | $httpProvider.defaults.useXDomain = true; delete $httpProvider.defaults.headers.common['X-Requested-With']; |
当我将"withCredentials"选项添加为true时,我在Web浏览器中出错:
从'http:// localhost:5000'访问来自'http://127.0.0.1:3005/login'的XMLHttpRequest已被CORS策略阻止:对预检请求的响应未通过访问控制检查:值当请求的凭据模式为"include"时,响应中的"Access-Control-Allow-Origin"标头不能是通配符"*"。 XMLHttpRequest发起的请求的凭据模式由withCredentials属性控制。
我尝试了很多来自stackoverflow的解决方案,但我失败了。
我希望具有相同的会话ID以执行身份验证。
您不能为"Access-Control-Allow-Origin"中使用通配符的服务器设置"withCredentials"标志。 您必须返回特定值"http:// localhost:5000"并添加标题为Access-Control-Allow-Credentials且值为"true"。 然后凭据请求发送凭证。