我错过了什么关于快速会话和饼干
What am I missing about express sessions and cookies?
我已经对express、express-session和express-sql-session进行了相当深入的研究。当用户登录时,我已经在数据库中为会话创建了一行。我是这样设置的:
//login route handler
this.bcrypt.compare(password, row.hashed, function(err, passwordsMatch) {
if (passwordsMatch === true) {
console.log("user now logged in");
req.session.user = row;
req.session.success = 'User successfully logged in';
res.send(row);
res.end();
}
});
片大好!我可以跳转到会话表并从数据库中获取行。
{"cookie":{"originalMaxAge":600000,"expires":"2015-08-24T23:16:20.079Z","httpOnly":false,"path":"/"},
"user":{"userID":24,"userName":"g","email":"g","joinDate":"2015-08-24T07:15:33.000Z"},"success":"User successfully logged in"}
注意,您可以看到设置了自定义use对象。但是,在下一次请求获取一些数据时,我检查会话上的user
对象:
// some other route called after login.
if (!req.session.user) {
console.log('user not authorized' + JSON.stringify(req.session));
res.send('not authorized');
return;
}
,但它记录一个(显然)空会话。
user not authorized{"cookie":{"originalMaxAge":600000,"expires":"2015-08-24T23:27:13.455Z","httpOnly":false,"path":"/"}}
进入浏览器,我还看到资源面板中没有设置cookie。这不应该用express4和session自动生成吗?医生说您不再需要expressCookie()来使用express 4了。如何在后续请求中获得正确的会话?
同样,如果我再次登录,它只是在会话表中创建一个重复的行。如何在响应中正确设置cookie以使其为下一个请求工作?
如果有帮助的话,下面是我的会话配置:
// at the beginning of my node server
import express = require('express');
import bodyParser = require('body-parser');
import Q = require('q');
import mysql = require('mysql');
var app = express();
import bcrypt = require('bcrypt');
import userModule = require('./userModule')
var UserRepository = new userModule.UserNamespace.UserRepository(connectToMySQL, bcrypt, Q );
import session = require('express-session');
var SessionStore = require('express-sql-session')(session);
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Credentials', 'true');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
var storeOptions = {
client: 'mysql',
connection: {
host:SQLHOST,
port:SQLPORT,
user:SQLUSER,
password: SQLPASS,
database: SQLDB
},
table: SESSION_TABLE,
expires: 365 * 24 * 60 * 60 * 1000
};
var sessionStore = new SessionStore( storeOptions );
app.use(session({
secret: 'meeogog',
resave: false,
saveUninitialized: false,
cookie: { maxAge: 600000,httpOnly: false },
store: sessionStore
}));
...
app.post('/users/login/', function (req, res) {
UserRepository.loginHashed(req, res);
});
..and then more routes, and so forth
就在我完成这个任务之后,我发现这是使用localhost和没有在xhr请求上设置usecredals的组合。本地主机是什么绊倒了我,你必须使用完全限定的127.0.0.1,更令人头痛的是,http文件是在不同的端口上提供的,所以必须更改通配符来反映这一点。
所以…
//where the server runs on 127.0.0.1:3000 but the http runs from :9000
app.use(session({
name:'some_session',
secret: 'lalala',
resave: true,
saveUninitialized: false,
cookie: { maxAge: 365 * 24 * 60 * 60 * 1000,httpOnly: false , domain:'127.0.0.1:9000'},
store: sessionStore
}));
res.header("Access-Control-Allow-Origin", "http://127.0.0.1:9000");
//important
$http request (angular): useCredentials: true
我曾经有过这样的问题。
ps:以下所有代码由:
MEAN.JS
刚开始使用护照:http://passportjs.org/
"passport": "~0.2.0",
"passport-facebook": "~1.0.2",
"passport-github": "~0.1.5",
"passport-google-oauth": "~0.1.5",
"passport-linkedin": "~0.1.3",
"passport-local": "~1.0.0",
"passport-twitter": "~1.0.2",
基本上我只是做:express.js
// CookieParser should be above session
app.use(cookieParser());
// Express MongoDB session storage
app.use(session({
saveUninitialized: true,
resave: true,
secret: config.sessionSecret,
store: new mongoStore({
db: db.connection.db,
collection: config.sessionCollection
})
}));
app.use( function (req, res, next) {
if ( req.method === 'POST' && (req.url === '/auth/signin'||req.url === '/auth/login') ) {
if ( req.body.rememberme ) {
req.session.cookie.maxAge = 2592000000; // 30*24*60*60*1000 Rememeber 'me' for 30 days
} else {
req.session.cookie.expires = false;
}
}
next();
});
// use passport session
app.use(passport.initialize());
app.use(passport.session());
创建一个passport.js
'use strict';
/**
* Module dependencies.
*/
var passport = require('passport'),
User = require('mongoose').model('User'),
path = require('path'),
config = require('./config');
/**
* Module init function.
*/
module.exports = function() {
// Serialize sessions
passport.serializeUser(function(user, done) {
done(null, user.id);
});
// Deserialize sessions
passport.deserializeUser(function(id, done) {
User.findOne({
_id: id
}, '-salt -password', function(err, user) {
done(err, user);
});
});
// Initialize strategies
config.getGlobbedFiles('./config/strategies/**/*.js').forEach(function(strategy) {
require(path.resolve(strategy))();
});
};
在策略文件夹中我做了这些文件:
locals.js
`
'use strict';
/**
* Module dependencies.
*/
var passport = require('passport'),
LocalStrategy = require('passport-local').Strategy,
User = require('mongoose').model('User');
module.exports = function() {
// Use local strategy
passport.use(new LocalStrategy({
usernameField: 'email',
passwordField: 'password'
},
function(email, password, done) {
User.findOne({
email: email
}).select('-__v -notes -tags').exec(function(err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false, {
message: 'Unknown user or invalid password'
});
}
if (!user.authenticate(password)) {
return done(null, false, {
message: 'Unknown user or invalid password'
});
}
user.password = undefined;
user.salt = undefined;
user.notes = undefined;
user.tags = [];
return done(null, user);
});
}
));
};
最后登录我只需要这样做:
user.auth.js
/**
* Signin after passport authentication
*/
exports.signin = function(req, res, next) {
console.log(req.body);
passport.authenticate('local', function(err, user, info) {
if (err || !user) {
res.status(400).send(info);
} else {
// Remove sensitive data before login
user.password = undefined;
user.salt = undefined;
user.notes = undefined;
user.tags = [];
user.resetPasswordToken = undefined;
req.login(user, function(err) {
if (err) {
res.status(400).send(err);
} else {
res.json(user);
}
});
}
})(req, res, next);
};
我一直感到同样的痛苦,为我工作的解决方案类似于FlavorScope。
我意识到express-session库在服务器上创建了一个cookie,但它没有保存在本地cookie中。响应头会说set-cookie,但没有保存。当我点击另一条路由,重新登录,等等,它不会工作,不会识别旧的会话(因为客户端/浏览器没有发送一个lol)。这就是为什么它在每条路线上都建立新的会话。这个问题似乎只能通过1.)在服务器上以某种方式设置cookie,以及2.)在客户端/浏览器上以某种方式设置任何get/post请求来解决。
我让我的工作没有更改为127.0.0.1。Localhost对我来说工作得很好。我还使用FETCH api,这是特定于如何设置头。这也是我的开发环境。我不得不把安全标志改为假。Localhost是http而不是https,所以如果开发环境的安全标志为真,它就会中断。还有最后一件事,当你有证书时:"包括"。在前端,您还需要使用特定域设置cors(这里我使用我的localhost), "*"通配符域名不工作。用我的话来说,我的资历是:"包括"。只是对浏览器说'嘿,如果我们从服务器得到一个cookie,你可以保存这个cookie ';
- 服务器
app.use(cors({ origin: "http://localhost:3000", credentials: true }));
app.use(session({ name: "mySession", secret: process.env.SESSION_SECRET, resave: false, saveUninitialized: false, cookie: { httpOnly: true, secure: false, maxAge: 60000 * 60 * 24 }, store: new RedisStore({ client: redisClient }) }))
Client/Browser for login and also another example for a get request
fetch( "http://localhost:3001/login", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email: email, password: password }), credentials : "include" } )
Get Request Example, still need the credentials: "include"
<pre><code>
fetch(
"http://localhost:3001/accounts",
{
method: "GET",
headers: {"Content-Type": "application/json"},
credentials: "include"
}
)
</pre></code>
- Flash Uploadify在调用我的MVC控制器时没有保留会话/授权
- 验证会话中是否存在对象's数组
- 通过javascript从会话中提取用户名
- 将会话变量从一个页面传递到另一个页面
- 如何保持会话的活力
- Codeigniter会话概念简要说明
- Php未获取会话的最新值
- 当达到codeigniter/tank auth会话超时时,在ajax调用中处理php重定向
- 如何检测用户是否在同一会话中打开了多个窗口或选项卡
- PHP会话页面刷新不起作用
- 有可能通过sessionID获得快速会话吗
- 让会话值可用于JavaScript的好方法是什么
- DreamFactory REST API POST休息/用户/会话请求总是在IE9中返回错误
- '会话'未定义-会话存储的Este JS/Express/Redis
- 如何使用 php 会话变量作为 Angular Js 数据
- jquery中设置的会话无法进入php
- 通过Javascript更改PHP会话变量
- 正在Javascript响应中设置会话变量
- 我错过了什么关于快速会话和饼干
- 让饼干比会话更持久