NodeJS:使用中间件保护一些路由

时间:2017-07-23 20:37:22

标签: javascript node.js api routing routes

我有两个文件:server.js和user.js,我想保护user.js中的一些路由,其中​​有一个用server.je编写的中间件。

server.js

//   :::::: G E T   T H E   P A C K A G E   W E   N E E D : :  :   :    :     :        :          :

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var morgan = require('morgan');
var mongoose = require('mongoose');
var cors=require('cors'); 
var jwt = require('jsonwebtoken'); // used to create, sign, and verify tokens
var config = require('./config'); // get our config file
// ─── GET an instance of the router for api routes ────────────────────────────────────────────────────────────────────────
var apiRoutes = express.Router();
var users =require('./app/routes/users'); 
//
// ────────────────────────────────────────────── II ──────────────────────────────────────────────────────────────────────
//   :::::: CONFIGURATION : :  :   :    :     :        :          :
var port = process.env.PORT || 1991; // used to create, sign, and verify tokens
mongoose.connect(config.database, { useMongoClient: true }); // connect to database
app.set('superSecret', config.secret); // secret variable

//
// ────────────────────────────────────────────── III ──────────────────────────────────────────────────────────────────────
//   :::::: USE BODY PARSER SO WE CAN GET INFO FROM POST AND/OR URL PARAMETERS : :  :   :    :     :        :          :
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
//   :::::: USE MORGAN TO LOG REQUESTS TO THE CONSOLE: :  :   :

app.use(morgan('dev'));
app.use(cors());


// ──────────────────────────────────────────────────────────────
//   :::::: R O U T E S : :  :   :    :     :        :          :
// ──────────────────────────────────────────────────────────────
// ───  A P I ROUTES ────────────────────────────────────────



//   :::::: MIDDLEWARE to secure route begin with /api: :  :   :  

apiRoutes.use(function(req, res, next) {

        console.log('hah');
    var token = req.body.token || req.query.token || req.headers['x-access-token'];


    if (token) {
    // verifies secret and checks exp
        jwt.verify(token, app.get('superSecret'), function(err, decoded) {
            console.log([err,decoded]);
            if (err) { //failed verification.
                return res.json({"error": true, success:false, message:'Faild to authenticate token'});
            }
            req.decoded = decoded;
            next(); //no error, proceed
        });
    } else {
        // forbidden without token
        return res.status(403).send({
            success: false,
            message: 'No token provided.'
        });
    }
});

apiRoutes.get('/', function(req, res) {
    res.json({ message: 'Welcome to the coolest API on earth!' });
});
app.use('/api', apiRoutes);
app.use('/user', users);

// ──────────────────────────────────────────────────
//   :::::: S T A R T the server: :  :   :    :     :          

app.listen(port);
console.log('Magic happens at http://localhost:' + port);

user.js的

const express=require('express'); 
const router=express.Router();
const passport= require('passport'); 
const jwt=require('jsonwebtoken');  

var userRoutes = express.Router();
var config = require('../../config'); // get our config file
var User = require('../../app/models/User'); // get our mongoose model


//
// ─── ROUTE TO REGISTER USER ──────────────────────────────────────────────────────────────────────
//
userRoutes.post('/signup', function(req, res) {
    if (!req.body.email ||  !req.body.password || !req.body.firstname || !req.body.lastname || !req.body.gender || !req.body.isTrainer) {
        res.json({ success: false, msg: 'set up required fields' });
    } else {
        var newUser = new User({
            email:      req.body.email,
            password:   req.body.password,
            firstname:  req.body.firstname,
            lastname:   req.body.lastname,
            gender:     req.body.gender,
            isTrainer:  req.body.isTraine   
        });
        User.find({ email: req.body.email}, function(err, user){
            if (err) {
                res.send({ success: false, msg:'authentication error'})
            }
            else if (user.length != 0) {
                res.send({success: false, msg:'Email already exists'})
                console.log(user);
            }else {
                // save the user
                newUser.save(function(err) {
                    if (err) {
                        console.log(err);       
                    }else {
                        res.send({ success: true, msg: 'Your account created successfully! ' });    
                    }

             });
            }
        })

    }
});

userRoutes.post('/signin', function(req, res) {
    User.findOne({
        email: req.body.email
    }, function(err, user) {
        if (err) throw err;

        if (!user) {
            res.send({ success: false, msg: 'Check your email' });
        } else {
            // check if password matches
            user.comparePassword(req.body.password, function(err, isMatch) {
                if (isMatch && !err) {
                    // if user is found and password is right create a token
                    var token = jwt.sign(user, config.secret,{
                        expiresIn: 0
                    });

                    // return the information including token as JSON
                    res.json({
                        success: true,
                        token: token,
                        username: user.username
                    });
                } else {
                    res.send({ success: false, msg: 'Check your password!' });
                }
            });
        }
    });
});

userRoutes.get('/users', function(req, res) {
    User.find({}, function(err, users) {
        res.json(users);
    });
});
module.exports= userRoutes; 

我想使用中间件保护/ 用户/用户,因此只有具有令牌的用户才能访问。请做一些建议或改变代码结构

1 个答案:

答案 0 :(得分:1)

我会创建一个看起来像这样的辅助模块(例如auth.js):

module.exports=function(req,res,next){
 //check user
 if(valid){
   next();
 }else{
  res.end("auth error");
 }
};

所以你可以随处都这样做:

app.use("/top-secret",require("auth.js"));
app.get("/top-secret/main",...);

如果你使用一些闭包来扩展辅助模块,它就会非常有用,例如:

module.exports.minLevel=function(level){
  return function(req,res,next){
    if(validUser && level<=user.level){
      next();
    }else{
      res.end("auth error");
    }
  };
};

用例

app.use("/admin",require("auth.js").minLevel(5));