如何通过Header传递JWT并通过Sails.js中的服务器端视图检索数据

时间:2016-01-15 14:10:09

标签: node.js express sails.js jwt express-jwt

后端:Sails.js

我已经为REST API实现了JSON Web Token,只有在通过Authorization Header接收到正确的JWT时,从前端到各种控制器的操作的所有AJAX请求才会返回数据res.json(data);。它按预期工作。

现在,我使用带有<%= name =>的EJS创建了一个视图,现在控制器具有详细信息res.view('/home', {name: "Bill"} );并将路由配置为指向相应的控制器。

如何从服务器端视图使用属性<%= name =>

对已经发布的JWT(存储在localStorage中)进行身份验证,从控制器中检索“名称”

感谢。

CODE:

视图/ index.ejs

<%= name =>

API /控制器/ UsersController.js

info: function(req, res) {

var userId = req.token;

Users.findOne(userId).exec(function(err, profile) {
    if(err) {
    res.json(err);
    } else {
       res.view('index',{
        name: profile.name,
    });
    }
});        
},

API /策略/ tokenAuth.js

module.exports = function(req, res, next) {
  var token;

  if (req.headers && req.headers.authorization) {
    var parts = req.headers.authorization.split(' ');
    if (parts.length == 2) {
      var scheme = parts[0],
        credentials = parts[1];

      if (/^Bearer$/i.test(scheme)) {
        token = credentials;
      }
    } else {
      return res.json(401, {err: 'Format is Authorization: Bearer [token]'});
    }
  } else if (req.param('token')) {
    token = req.param('token');
    delete req.query.token;
  } else {
    return res.json(401, {err: 'No Authorization header was found'});
  }

  sailsTokenAuth.verifyToken(token, function(err, token) {
    if (err) return res.json(401, {err: 'Please Logout and Login again!'});

    req.token = token;

    next();
  });
};

API /服务/ sailsTokenAuth.js

var jwt = require('jsonwebtoken');

module.exports.issueToken = function(payload) {
  var token = jwt.sign(payload, process.env.TOKEN_SECRET || "xxxxxxx");
  return token;
};

module.exports.verifyToken = function(token, verified) {
  return jwt.verify(token, process.env.TOKEN_SECRET || "xxxxxxx", {}, verified);
};

配置/ routes.js

module.exports.routes = {
    '/': {
        controller: 'UsersController',
        action: 'info'
      },
};

SOLUTION:

要将JWT用作从客户端浏览器到服务器的身份验证因素,可以使用localStorage或会话cookie。我最终将其缩小到使用cookie,因为在服务器中更容易实现。

在对用户进行身份验证后,将JWT存储在客户端浏览器中

res.cookie('jwttoken', sailsTokenAuth.issueToken(profile.name));

然后可以使用req.cookies.jwttoken检索它并通过服务(jwt.verify)验证它,以通过res.jsonres.view

访问所请求的信息

1 个答案:

答案 0 :(得分:5)

无法看到您提供的任何代码,但可以说您设置了自定义政策 api / policies / jwt.js 等,然后在那里查看每个请求都有JWTToken。类似的东西(为简单起见忽略任何错误处理):

module.exports = function (req, res, next) {

    var token = req.headers.authorization.split(' ')[1];
    var payload = jwt.decode(token, config.TOKEN_SECRET);
    req.userId = payload.sub;
    next();
};

注意我如何将userId附加到 req 对象( req.userId = payload.sub; )。这意味着在您的控制器中,您可以访问 userId (或者在您的情况下,无论您使用哪个ID来识别您的登录用户等),您都可以从传入的 req 对象引用它。

显然,您对JWT策略的实现可能会有所不同,但只需将其自定义为上述内容即可。如果您实际上将名称保留在jwt令牌中(无法看到您的实现),那么只需将其附加到req对象(不需要模型查找)。

获得所需的名称后,将其传递给您的视图(因为您目前正在使用上面的硬编码值 Bill

根据更新的问题进行更新

因此,根据您的评论和更新的问题,您已设法从JWT令牌中提取配置文件信息,并从模型查找中获取所需的配置文件信息。您现在无法在EJS视图中显示该名称。

所以你可以实现这样的目标:

控制器:

res.view('index', {
        name: profile.name
    }

请注意我在profile.name后删除了逗号;)

config / views.js 应设置为&#34; ejs&#34;如果那是你正在使用的模板引擎。

其余的看起来不错。至少,符合我的预期。

最好的办法是在controller.info方法返回之前显式使用调试器或至少是console.log语句,并确保profile.name按预期设置。如果你走得那么远,那么你就会知道问题在于路由以某种方式查看。

您可以尝试在视图下创建子文件夹,也可以重命名视图文件(索引稍微特别..)。执行类似 views / xxx / yyy.ejs

的操作

还暂时注释掉你的controller.info方法,并用一些非常简单的东西替换它:

res.view('xxx/yyy', {
            name: 'bob'
        });

根据进一步的用户反馈进一步更新

从上次评论开始,您的问题正逐步发展......

我认为您现在所说的是Sails代码全部正常运行,并且使用Postman进行了验证。但是在使用Web浏览器客户端时失败,因为您的客户端代码未在http标头中传递正确的令牌信息。

如果是这种情况,您需要在客户端上创建一个以编程方式应用标头信息的拦截器。

EG。 (只是从Angular工厂的authInterceptor中取出的一个片段,但这里没有显示任何特定的角度):

 request: function (config) {
      var token = authToken.getToken();

      if (token) {
        config.headers.Authorization = 'Bearer ' + token;
      }

      return config;
    },

上面,根据请求,JWT是从本地存储(你说你已经工作)检索的,如果令牌存在,那么http头信息会更新为表格的授权标题不记名令牌&#39;。

我没有看过你的回购,说实话,我确实觉得我已经给了你很多信息。根据我提供的内容,也许还有一些谷歌搜索/测试你应该能够得到一个有效的解决方案。