Ajax请求cors和cookies步骤

时间:2017-10-25 16:26:52

标签: javascript ajax request cors

我在localhost:1841处有一个客户端前端,在localhost:9000处有一个后端。

我的身份验证系统使用简单的几个用户名/密码来提供Json Web令牌(jwt)。

当我的客户收到令牌时,我要求他用javascript将其保存在cookie中。但是当我从我的客户端(:1841)到我的服务器(:9000)进行XmlhttpRequest调用时,请求中没有cookie 。所以我的服务器提供了401(行为没问题)。 我知道这是正常的,因为相同的起源 - 政策,所以没有发送来自cookie的信息。

我使用extjs 6作为客户端,使用节点js作为服务器。

在服务器端和客户端配置的所有步骤是什么?

在服务器端,我已经授权了cors请求。 我听说过httpOnly?但我不知道如何处理它?<​​/ p>

从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{
              ....
            }
        }
    });
}

2 个答案:

答案 0 :(得分:1)

根据您使用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时,您可以从标头获取令牌。

答案 1 :(得分:0)

客户端JavaScript只能为当前源设置cookie。

其他来源将拥有自己的一套Cookie。

您需要:

  • 使用HTTP
  • 从:9000来源设置Cookie
  • 通过其他一些机制(例如POST正文中的值)传递数据。