即使对于上面的路由,ExpressJS授权中间件也会被执行

时间:2017-04-14 08:08:12

标签: node.js express

我正在研究一个具有完整MEAN堆栈的大学/学生项目。我们有NodeJS,ExpressJS后端和Angular2前端。后端在localhost:8080上运行,前端在localhost:4200上运行

这就是我后端的样子

var express = require('express'),
...
var app = express();

...

// needed because of cross origin resource sharing during development
app.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
});

var port = process.env.PORT || 8080;

var loginController = require('./controllers/loginController')(Person);
var personController = require('./controllers/personController')(Person, Transaction);
var transactionController = require('./controllers/transactionController')(Person, Transaction);

var apiRouter = express.Router();

apiRouter.post('/login', loginController.authenticate);

/**
 * Middleware that handles authorization of particular routes.
 * Every request which starts with `/api/persons` or `/api/transactions`, will be intercepted and validated against JWT.
 */
apiRouter.use(function (req, res, next) {
    // JWT gets validated
});

apiRouter.get('/persons', personController.fetchAllPersons);

apiRouter.get('/persons/:personId', personController.fetchPersonById);

apiRouter.get('/persons/:personId/transactions', personController.fetchTransactionsByPersonId);

apiRouter.post('/transactions', transactionController.addNewTransaction);

app.use('/api', apiRouter);

app.listen(port, function () {
    console.log('Listening on port: ' + port);
});

我读到快递路由器的路由按顺序执行,因此中间件包含的顺序很重要。因此我在/login路由之后设置它,因为没有JWT授权它不应该可用。 当我启动应用程序并使用postman执行请求时,一切都按预期工作,但是当我尝试从前端登录中间件时,也会执行登录路由,但它不应该,对吧?

可能是因为他们在不同的端口上运行,或者它可能是由交叉起源引起的问题,我真的不知道? 有没有人已经面临类似的问题,你能解释一下这种行为吗? THX

编辑1:

正如robertklep在下面提到的,它可能取决于loginController实现以及我们如何处理前端登录的方式,这里是代码片段

jwt = require('jsonwebtoken');

var loginController = function (Person) {
    var authenticate = function (req, res) {
        req.person = req.body;
        var searchPerson = { username: req.person.username }
        Person.findOne(searchPerson, function (err, person) {
            if (err) throw err;

            if (!person) {
                return res.status(401).send({ message: 'Wrong username/password' });
            }

            person.comparePasswords(req.person.password, function (err, isMatch) {
                if (err) throw err;

                if (!isMatch) {
                    return res.status(401).send({ message: 'Wrong username/password' });
                }

                var token = jwt.sign(person._id, /* XXX SECRET XXX */);
                res.status(200).json({
                    token: token,
                    person: person
                });
            });
        });
    };

    return {
        authenticate: authenticate
    };
};

module.exports = loginController;

前端:

...
export class LoginComponent implements OnInit {
 /**
   * validates input data and on successful validation,
   * tries to login the user with her/his credentials
   */
  public login(): void {
    // validation logic should consider all fields, no matter if the user has entered any data
    this.validate(false);
    // no validation error, continue with login process
    if(!this.errorMessage){
      const form = this.loginForm;
      var credentials = {
        name: form.get('name').value,
        password: form.get('password').value  
      };
      this.loginService.login(credentials.name,credentials.password)
      .subscribe(
        name => this.router.navigate(['welcome']),
        error => this.errorMessage = error);
    }
  }
}

...
export class LoginService {
...
public login(userName: string, password: string): Observable<string> {
        var person = {
            'username': userName,
            'password': password
        };
        return this.http.post('http://localhost:8080/api/login',person)
            .map(this.extractToken)
            .catch(this.handleError);
    }
}

编辑2:

据我所知,我发布了我的中间件,所以这就是它的样子

apiRouter.use(function(req, res, next) {
    // first, check if a token is provided
    var token = req.body.token || req.query.token || req.headers['x-access-token'];
    if (token) {
        // token gets validated by jwt lib
        jwt.verify(token, /* SECRET */, function (err, decoded) {
            if (err) {
                // token invalid, respond with unauthorized
                res.status(401).json({
                    message: 'Failed to authenticate token.'
                });
            } else {
                // token is valid, continue to the particular request handler
                req.decoded = decoded;
                next();
            }
        });
    } else {
        // token was not provided, respond with forbidden
        res.status(403).json({
            message: 'No token provided.'
        });
    }
});

就像我说的,当我使用postman客户端并执行登录请求时,一切都按预期工作(中间件不会执行登录请求)但是当我启动我们的前端应用程序并执行相同操作时,中间件函数会被执行

0 个答案:

没有答案