Vij*_*ran 1 node.js express jwt sails.js express-jwt
后端:Sails.js
我已经为REST API实现了JSON Web Token,其中从前端到各种控制器的操作的所有AJAX请求res.json(data);只有在通过Authorization Header接收到正确的JWT时才返回数据.它按预期工作.
现在,我已经使用EJS创建了一个视图<%= name =>,现在控制器具有详细信息res.view('/home', {name: "Bill"} );并将路由配置为指向相应的控制器.
如何通过从具有该属性的服务器端视图使用已发布的JWT(存储在localStorage中)进行身份验证来从控制器检索"名称" <%= name =>
谢谢.
码:
意见/ index.ejs
<%= name =>
Run Code Online (Sandbox Code Playgroud)
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,
});
}
});
},
Run Code Online (Sandbox Code Playgroud)
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();
});
};
Run Code Online (Sandbox Code Playgroud)
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);
};
Run Code Online (Sandbox Code Playgroud)
配置/ routes.js
module.exports.routes = {
'/': {
controller: 'UsersController',
action: 'info'
},
};
Run Code Online (Sandbox Code Playgroud)
解:
要将JWT用作从客户端浏览器到服务器的身份验证因素,可以使用localStorage或会话cookie.我最终将其缩小到使用cookie,因为在服务器中更容易实现.
在对用户进行身份验证后,将JWT存储在客户端浏览器中,
res.cookie('jwttoken', sailsTokenAuth.issueToken(profile.name));
Run Code Online (Sandbox Code Playgroud)
然后可以使用它来检索req.cookies.jwttoken它并通过服务(jwt.verify)验证它,以通过res.json或访问所请求的信息res.view
看不到任何代码,如未提供,但可以说你设置了自定义策略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();
};
Run Code Online (Sandbox Code Playgroud)
注意我是如何将userId附加到req对象(req.userId = payload.sub;).这意味着在您的控制器中,您将可以访问userId(或者在您的情况下,您使用任何ID来识别您的登录用户等),因为您可以从传入的req对象中简单地引用它.
显然,您对JWT策略的实现可能会有所不同,但只需将其自定义为上述内容即可.如果您实际上将名称保存在jwt令牌中(无法看到您的实现),那么只需将其附加到req对象(不需要模型查找).
获得所需名称后,将其传递给您的视图(因为您目前正在使用上面的硬编码值Bill.
根据更新的问题更新
因此,根据您的评论和更新的问题,您已设法从JWT令牌中提取配置文件信息,并从模型查找中获取所需的配置文件信息.您现在无法在EJS视图中显示该名称.
所以你可以实现这样的事情:
控制器:
res.view('index', {
name: profile.name
}
Run Code Online (Sandbox Code Playgroud)
注意我在profile.name;后删除了逗号;)
如果这是您正在使用的模板引擎,则应将config/views.js设置为"ejs".
其余的看起来不错.至少,符合我的预期.
最好的办法是在controller.info方法返回之前显式使用调试器或至少是console.log语句,并确保profile.name按预期设置.如果你走得那么远,那么你就会知道问题在于以某种方式查看路由.
您可以尝试在视图下创建子文件夹,也可以重命名视图文件(索引稍微特殊..).做一些像views/xxx/yyy.ejs
还暂时注释掉你的controller.info方法,并用一些非常简单的东西替换它:
res.view('xxx/yyy', {
name: 'bob'
});
Run Code Online (Sandbox Code Playgroud)
根据进一步的用户反馈进一步更新
从您上次的评论来看,您的问题正在逐步发展......
我认为你现在所说的是Sails代码全部正常工作,并且使用Postman进行了验证.但是在使用Web浏览器客户端时失败,因为您的客户端代码未在http标头中传递正确的令牌信息.
如果是这种情况,您需要在客户端上创建一个以编程方式应用标头信息的Interceptor.
例如.(只是从Angular工厂authInterceptor中取出的一个片段,但这里没有显示角度特定的):
request: function (config) {
var token = authToken.getToken();
if (token) {
config.headers.Authorization = 'Bearer ' + token;
}
return config;
},
Run Code Online (Sandbox Code Playgroud)
上面,根据请求,从本地存储(您说您已经工作)检索JWT,如果令牌存在,则使用" 承载令牌 " 形式的授权标头更新http标头信息.
我没有看过你的回购,说实话我觉得我已经给了你很多信息.根据我提供的内容,也许还有一些谷歌搜索/测试你应该能够得到一个有效的解决方案.
| 归档时间: |
|
| 查看次数: |
7049 次 |
| 最近记录: |