我在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用于setget令牌或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时,可以从标头中获取令牌。

07-24 09:38
查看更多