【问题标题】:Authorizarion on json-server with a JWT使用 JWT 对 json-server 进行授权
【发布时间】:2020-06-12 22:55:33
【问题描述】:

我正在尝试制作一个使用 typicode json-server 的节点应用程序,我想向应用程序添加授权,其中 GET 请求对所有公众开放,但 PUT、POST 和 DELETE 请求需要 JWT 令牌,然后才他们可以继续使用 api。

我尝试制作一个小应用程序,但由于我是前端开发人员,我无法弄清楚授权的下一部分以及如何在节点上使用中间件。

这是我编写的应用程序。

    const jsonServer = require('json-server')
    const app = jsonServer.create()
    const router = jsonServer.router('db.json')
    const middlewares = jsonServer.defaults()
    const morgan = require('morgan');
    const jwt = require('jsonwebtoken');
    const config = require('./config');
    const bodyParser = require('body-parser');

    app.set('Secret', config.secret);
    app.use(morgan('dev'));
    app.use(bodyParser.urlencoded({ extended: true }));
    app.use(bodyParser.json());

    app.use(middlewares)
    app.use((req, res, next) => {
        if (req.method === 'GET') {
            console.log(req);
            next();
        } else {
            if (req.path === '/login') {
                getToken(req, res);
            }
            if (isAuthorized(req, res)) {
                console.log("I am here");
                next();
            } else {
                console.log("I am in error");
                res.sendStatus(401)
            }
        }
    })
    app.use(router)
    app.listen(3000, () => {
        console.log('JSON Server is running on 3000')
    })

    function isAuthorized(req, res) {

        console.log("sadasdasdasd");

        var token = req.headers['access-token'];
        console.log(token);
        // decode token
        if (token) {
            console.log("Inside token");
            jwt.verify(token, app.get('Secret'), (err, decoded) => {
                console.log("Inside JWT fn");
                if (err) {
                    console.log("Inside JWT fn err");
                    return res.json({ message: 'invalid token' });
                } else {
                    console.log("Inside JWT fn success");
                    req.decoded = decoded;
                    return true;
                }
            });

        } else {
            // if there is no token  
            res.send({
                message: 'No token provided.'
            });
        }
    }

    function getToken(req, res) {
        if (req.body.username === "test") {
            if (req.body.password === 123) {
                const payload = {
                    check: true
                };
                var token = jwt.sign(payload, app.get('Secret'), {
                    expiresIn: 1440 // expires in 24 hours
                });
                res.json({
                    message: 'Authentication Successful ',
                    token: token
                });
            } else {
                res.json({
                    error: 'Invalid Password',
                });
            }
        } else {
            res.json({
                error: 'Please provide valid credentials',
            });
        }
    } 

【问题讨论】:

    标签: javascript node.js reactjs vue.js json-server


    【解决方案1】:

    你做对了。但是,您的 isAuthorized 中间件有一些问题。在中间件中你有一个异步动作(jwt.verify),那么你不能像json-server的官方文档那样把这个函数作为一个“辅助函数”(函数返回布尔值)。

    isAuthorized成为一个中间件,你就像一个中间件:

    function isAuthorized(req, res, next) { // Pass 3 parmas to a express middleware 
    
      console.log("sadasdasdasd");
    
      var token = req.headers['access-token'];
      console.log(token);
      // decode token
      if (token) {
        console.log("Inside token");
        jwt.verify(token, app.get('Secret'), (err, decoded) => {
          console.log("Inside JWT fn");
          if (err) {
            console.log("Inside JWT fn err");
            return res
              .status(401) // I think will be better if you throw http status is 401 to client
              .json({ message: 'invalid token' });
          } else {
            console.log("Inside JWT fn success");
            req.decoded = decoded;
            return next(); // Only call "next" if everything is good, continue next jobs - handle secured requests
          }
        });
    
      } else {
        // if there is no token  
        return res
        .status(401)
        .send({
          message: 'No token provided.'
        });
      }
    }
    

    使用中间件

        app.use((req, res, next) => {
            if (req.method === 'GET') {
                console.log(req);
                next();
            } else {
                if (req.path === '/login') {
                    getToken(req, res);
                }
                isAuthorized(req, res, next); // Here
            }
        })
    

    【讨论】:

      猜你喜欢
      • 2019-03-19
      • 2021-08-17
      • 2020-12-17
      • 2019-09-23
      • 2019-06-04
      • 2019-06-13
      • 2018-12-05
      • 2016-07-20
      • 2019-09-17
      相关资源
      最近更新 更多