我在localhost:1841有一个客户端前端,在localhost:9000有一个后端。
我的身份验证系统使用简单的几个用户名/密码来传递Json Web令牌(jwt)。
当我的客户收到令牌时,我请他使用JavaScript将其保存在Cookie中。但是,当我从客户端(:1841)到服务器(:9000)进行XmlhttpRequest调用时,请求中没有cookie。因此,我的服务器发送了401(行为正常)。
我知道这很正常,由于SAME-ORIGIN-POLICY,因此不会发送Cookie的任何信息。
我使用extjs 6作为客户端,使用节点js作为服务器。
要在服务器端和客户端中进行配置,需要执行所有这些步骤?
在服务器端,我已经授权了cors请求。
我听说过httpOnly吗?但我不知道该如何处理?
要求从localhost:1841(extjs客户端)登录:
Ext.Ajax.request({
url: 'http://localhost:9000/api/users/authenticate/',
method: 'POST',
params: params,
success: function(response){
var text = response.responseText;
var data = Ext.decode(text, true);
if(data.access_token){
me.saveToken(data.access_token);
me.createInterface();
} else {
if(data.message){
Ext.Msg.alert("Bummer", data.message);
} else {
Ext.Msg.alert("Bummer", "Something went wrong.");
}
}
},
配置CORS:
cors = require('cors');
...
...
...
var whitelist = ['http://127.0.0.1:9000', 'http://localhost:8080', 'http://localhost:9000', 'http://127.0.0.1:8080', 'http://localhost:1841', 'http://127.0.0.1:1841']
var corsOptionsDelegate = function (req, callback) {
var corsOptions;
if (whitelist.indexOf(req.header('Origin')) !== -1) {
corsOptions = { origin: true } // reflect (enable) the requested origin in the CORS response
}else{
corsOptions = { origin: false } // disable CORS for this request
}
callback(null, corsOptions) // callback expects two parameters: error and options
}
...
module.exports = function(app) {
....
app.use(cors(corsOptionsDelegate));
}
客户的其他电话:
Ext.ajax.request({
url : 'http://localhost:9000/api/users/'
method : 'POST'
success: function(response){
var text = response.responseText;
var data = Ext.decode(text, true);
...
...
}
},
})
来自服务器的验证:
function isAuthenticated() {
return compose()
// Validate jwt
.use(function (req, res, next) {
....
....
console.log(req.headers.authorization);
validateJwt(req, res, function (err) {
if (err) {
console.log(err.inner.name);
if (err.inner.name === "TokenExpiredError") {
// client have to request token with his refresh_token
return next({"error":err.inner.name});
}
}
next();
});
})
.use(function (req, res, next) {
....
});
});
编辑1:
我在节点中添加了Set-Cookie,并且Set-Cookie出现在响应标题中以及来自DevTools的预览cookie中。但是未在浏览器中设置cookie。
exports.authenticate = function(req, res, next){
User.findOne({
fullName: req.body.username
}, function(err, user) {
....
if (!user) {
res.status(401).json({
success: false,
message: 'Authentication failed. User not found.'
});
} else {
// Check if password matches
if(user.authenticate(req.body.password)){
var access_token = jwt.sign(user, config.secrets.session, {
expiresIn: 60 // in seconds
});
res.cookie('access_token',access_token);
res.status(200).json({
"success": true,
"access_token" : access_token
//token: 'JWT ' + token
});
}else{
....
}
}
});
}
最佳答案
按照您使用ExtJS Ajax的方式,因此可以使用defaultXhrHeader属性将令牌从客户端发送到服务器端。
首先,当您调用身份验证请求以获取令牌时。在这里,您可以将ExtJS Cookies用于set和get令牌或cookie。
Ext.Ajax.request({
url: 'http://localhost:9000/api/users/authenticate/',
params: params,
method: 'POST',
success: function(response, opts) {
var data = Ext.decode(response.responseText;);
if (data.access_token) {
//Set cookie in our client side using Utility class for setting/reading values from browser cookies.
Ext.util.Cookies.set('access_token', data.access_token);
} else {
if (data.message) {
Ext.Msg.alert("Bummer", data.message);
} else {
Ext.Msg.alert("Bummer", "Something went wrong.");
}
}
},
failure: function(response, opts) {
console.log('server-side failure with status code ' + response.status);
}
});
现在您需要使用Ajax传递相同的令牌defaultXhrHeader请求
这是示例:-
Ext.Ajax.request({
url: 'http://localhost:9000/api/users/',
method: 'POST', //As per method acceptance you can use (GET,PUT,DELETE).
//send cookie sever side using defaultXhrHeader
defaultHeaders: {
'access_token': Ext.util.Cookies.get('access_token'),
'Content-Type': 'application/json;charset=utf-8'
},
success: function(response, opts) {
var data = Ext.decode(response.responseText;);
//Put your logic here.
},
failure: function(response, opts) {
console.log('server-side failure with status code ' + response.status);
}
});
在服务器端使用NodeJ时,可以从标头中获取令牌。