我正在尝试在nodejs中构建一个简单的web令牌protected api。我一直在关注本教程authenticate a node js api with json web tokens,并一直在我的应用中实施这些步骤。我现在有一个允许我获取/发布/放置/删除的api运行,并为用户生成webtoken并以纯文本形式显示它(用于开发目的)。我正在使用节点restful api的,但我有一些麻烦理解如何实际验证客户端是否发送webtoken在他们的请求,允许这些get/post/put/delete请求之前。使用Json Web令牌的Node-Restful
这是我的路由器。在那里我定义允许的请求:
const express = require('express')
const router = express.Router()
// Models - Load models here
var userModel = require('./models/User')
// Controllers - Load controllers here
const userController = require('./controllers/userController')
// Routes - Define routes here
router.post('api/authenticate', userController.authenticate) //Route that generates the webkey and shows it in the response
// Configure the endpoint that node-restful will expose. Here I want to first check if the user is sending his or her api key. Before allowing these methods.
userModel.methods(['get', 'put', 'post', 'delete'])
userModel.register(router, '/api/users')
// Export the router object
module.exports = router
这里是我的userController生成令牌。
// Dependencies
const User = require('../models/User')
const jwt = require('jsonwebtoken')
const config = require('../config.js')
module.exports = {
authenticate: function(req, res, next) {
// find the user
User.findOne({username: req.body.name}, function(err, user) {
if (err) throw err;
if (!user) {
res.json({
success: false,
message: 'Authentication failed. User not found.' });
} else if (user) {
// check if password matches
if (user.password != req.body.password) {
res.json({
success: false,
message: 'Authentication failed. Wrong password.' });
} else {
// if user is found and password is right
// create a token
var token = jwt.sign(user, config.secret, {
expiresIn: 60*60*24 // expires in 24 hours
});
// return the information including token as JSON
res.json({
success: true,
message: 'Enjoy your token!',
token: token
});
}
}
})
}
}
这里是我的用户模型。
// Dependencies
const restful = require('node-restful')
const mongoose = restful.mongoose
// Schema
const userSchema = new mongoose.Schema({
username: String,
password: String,
email: String
})
// Return the model as a restful model to allow it being used as a route.
module.exports = restful.model('User', userSchema)
是否有某种方式可以保护这些端点,使用与我目前使用的相同的语法来公开它们?我相信我会定义方法之前,请检查网络令牌:
userModel.methods(['get', 'put', 'post', 'delete'])
userModel.register(router, '/api/users')
如果我只是删除方法本身,用户将无法获得页面,并显示一个:“不能GET/api/users“错误。如果我想显示自定义错误怎么办?例如:“没有提供Web令牌,注册认证”等等?任何帮助深表感谢。先谢谢你。
我现在有一个函数可以在服务页面之前检查令牌。它似乎现在工作。目前,我在postman中手动传递令牌作为头文件:x-access-token。如何在生成时捕获令牌并自动让客户端在未来的请求中发送令牌?这是检查令牌和受保护路由的函数。
太好了。我在等待任何答案的同时继续工作,并完成了此步骤。我现在可以生成令牌并使用邮递员传递给我创建的安全路线。它的工作原理非常完美,但我很努力地理解我将如何在客户端保存令牌并在每个请求上传递该令牌。我仍然生成令牌,如上所述。我可以通过手动将它作为x-access-token传递给我的头部来验证令牌,但我该如何自动执行此操作?
更新
这里是检查利用该功能的令牌和一个受保护的路由功能:
//路线 - 这里定义路线
function getToken(req, res, next) {
var token = req.body.token || req.query.token || req.headers['x-access-token'];
// decode token
if (token) {
// verifies secret and checks exp
jwt.verify(token, config.secret, function(err, decoded) {
if (err) {
return res.json({ success: false, message: 'Failed to authenticate token.' });
} else {
// if everything is good, save to request for use in other routes
req.decoded = decoded;
console.log(decoded);
next();
}
});
} else {
// if there is no token
// return an error
return res.status(403).send({
success: false,
message: 'No token provided.'
});
}
}
router.get('/entries', getToken, entryController.get)
我发现这个问题save-token-in-local-storage-using-node解决了最后一块难题。
太好了。我在等待任何答案的同时继续工作,并完成了此步骤。我现在可以生成令牌并使用邮递员传递给我创建的安全路线。它的工作原理非常完美,但我很努力地理解我将如何在客户端保存令牌并在每个请求上传递该令牌。我仍然生成令牌,如上所述。我可以通过手动将它作为x-access-token传递给我的头部来验证令牌,但我该如何自动执行此操作?检查我的更新问题的代码。 – n0rd
查看已更新的答案。 – Tolsee
太棒了。我想知道这是否是我应该做的。所以我需要将这个标记保存为一个cookie,这应该不是我目前在我的令牌生成中使用的json响应。它是否正确? – n0rd