如何在单个快速路由 User.route('/').get((req,res,next)=> ) 上添加两个身份验证?

Posted

技术标签:

【中文标题】如何在单个快速路由 User.route(\'/\').get((req,res,next)=> ) 上添加两个身份验证?【英文标题】:How to add two authentication on single express Route User.route('/').get((req,res,next)=> ) in this?如何在单个快速路由 User.route('/').get((req,res,next)=> ) 上添加两个身份验证? 【发布时间】:2021-07-04 12:26:01 【问题描述】:

我有两个passport-jwt认证

    验证用户 验证合作伙伴

我希望用户以及基于身份验证的合作伙伴都可以访问我添加的合作伙伴。

这是我使用的一些代码,但它响应未授权:

路线: partnerRoute.js

const bodyParser=require('body-parser');
const Partner=require('../model/partner');
const Place=require('../model/place');
const auth=require('../authentication/auth');
const permission=require('../authentication/verifypermission');
const place = require('../model/place');

const partnerRouter=express.Router();
partnerRouter.use(bodyParser.json());

partnerRouter.route('/login')
.post((req,res,next)=>
   Partner.findOne(email:req.body.email)
   .then((data)=>
       if(auth.authenticate(req.body.password,data.hash_password))
       
           res.end(auth.getToken(_id: data._id));
       
   )
   .catch((err)=>
       console.log(err);
   )
);
partnerRouter.route('/register')
.post((req,res,next)=>
    Partner.findOne(email:req.body.email)
   .then((data)=>
       if(data)
       
            res.end('Partner already exist with Email '+req.body.email);
       
       else
       
            Partner.findOne(contact:req.body.contact)
            .then((data)=>
                if(data)
                
                    res.end('Partner already exist with Contact '+req.body.contact);
                
                else
                    Partner.create(req.body)
                    .then((data)=>
                            res.json("Message":"Partner Successfully Created.")
                    )
                    .catch((err)=>
                        console.log(err);
                    );
                
            )
            .catch((err)=>
                console.log(err);
            );
       
   )
   .catch((err)=>
       console.log(err);
   );

);

partnerRouter.route('/places/:partnerid')
.get(auth.verifyPartner,auth.verifyUser, (req,res,next)=>
    permission.verifyPermission(req.user._id,req.params.partnerid,(err,data)=> // verifyPermission just use to check role of users.
        if(err)
        
            console.log(err);
        
        if(data=='Permission_granted')
        
            place.find(partner_id:req.params.partnerid)
            .then((data)=>
                res.json(data);
            )
            .catch((err))
        
        else
            res.end(data)
        
    )
)
module.exports=partnerRouter;

userRoute.js

const express=require('express');
const bodyParser=require('body-parser');
const User=require('../model/user');
const User_detail=require('../model/user_detail');
const auth=require('../authentication/auth');
const permission=require('../authentication/verifypermission');

const usersRouter = express.Router();

usersRouter.use(bodyParser.json());

usersRouter.route('/login')
.post((req,res,next) => 
   User.findOne( email: req.body.email )
   .then((userdata)=>
        if(userdata)
        
            if(auth.authenticate(req.body.password,userdata.hash_password))
                                  
                res.end(auth.getToken(_id: userdata._id));
            
            else
                res.end("Password Missmatch")
               
        
        else
        
            res.end("Check your email address");
        
   )
   .catch((err)=>
       console.log(err);
   )
); 

usersRouter.route('/register')
.post((req,res,next)=>
    User.findOne(email: req.body.email)
    .then((data)=>
            if(data)
               
                res.end("User Already Exist with email: "+req.body.email);
            
            else
            
            User.findOne(contact: req.body.contact)
            .then((data)=>
                if(data)
                    res.end("User Already Exist with contact number: "+req.body.contact)
                
                else
                
                    if(req.body.password)
                    
                        req.body.hash_password=auth.encryptPassword(req.body.password);
                    
                    User.create(req.body)
                    .then((data)=>
                        res.json("message": "user Successfully created");
                    )
                    .catch((err)=>
                        console.log(err);
                    )
                
            )
        
    )
    .catch((err)=>
        console.log(err);
    );
);

module.exports= usersRouter;

身份验证 auth.js

const jwt=require("jsonwebtoken");
const bcrypt=require("bcrypt");
// const passport=require('passport');
var Passport = require('passport').Passport,
    passport = new Passport(),
    partnerPassport = new Passport();
const ExtractJwt=require('passport-jwt').ExtractJwt;
const JwtStrategy=require('passport-jwt').Strategy;
const User=require("../model/user");
const Partner = require("../model/partner");

module.exports.getToken = function(user) 
    return jwt.sign(user, '12345-67890-09876-54321',
        expiresIn: 3600);
;
module.exports.encryptPassword = function(password) 
    return bcrypt.hashSync(password, 10);
;
module.exports.authenticate = function(password,hash_password) 
    return bcrypt.compareSync(password,hash_password);
;

var opts=
    opts.secretOrKey = '12345-67890-09876-54321';
    opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();

module.exports.Jwtpassport=passport.use(new JwtStrategy(opts,
    function(jwt_payload,done)
        // console.log("JWT payload: ", jwt_payload);
        User.findOne(_id: jwt_payload._id,function(err,userdata)
            if(err)
            
                return done(err, false);
            
            if(userdata)
            
                return done(null, userdata);
            
            else
            
                return done(null, false);
            
        )

))

module.exports.Jwtpartnerpassport=partnerPassport.use(new JwtStrategy(opts,
    function(jwt_payload,done)
        // console.log("JWT payload: ", jwt_payload);
        Partner.findOne(_id: jwt_payload._id,function(err,partnerdata)
            if(err)
            
                return done(err, false);
            
            if(partnerdata)
            
                return done(null, partnerdata);
            
            else
            
                return done(null, false);
            
        )
))

module.exports.verifyUser = passport.authenticate('jwt', session: false);
module.exports.verifyPartner = partnerPassport.authenticate('jwt', session: false);

型号 用户.js

const mongoose=require('mongoose');
const bcrypt=require('bcrypt');

const userSchema= new mongoose.Schema(
    firstname:
    
        type:String,
        require: true,
        trim:true,
        min:3,
        max:15
    ,
    lastname:
    
        type:String,
        require: true,
        trim:true,
        min:3,
        max:15
    ,
    email:
    
        type:String,
        require: true,
        trim:true,
        unique:true,
        lowercase:true
    ,
    contact:
    
        type:String,
        require: true,
        unique:true
    ,
    hash_password:
    
        type:String,
        require:true
    ,
    role:
    
        type:String,
        enum:['user','admin'],
        default:'user'
    ,
    profile_picture:
    
        type:String
    ,
    status:
    
        type:Boolean,
        default:1
    

, timestamps:true );

userSchema.virtual('password')
.set(function(password)
    this.hash_password=bcrypt.hashSync(password, 10);
);

module.exports = mongoose.model('User',userSchema); 

合作伙伴.js

const mongoose=require('mongoose');
const bcrypt=require('bcrypt');

const partnerSchema=mongoose.Schema(
    firstname:
    
        type:String,
        require: true,
        trim:true,
        min:3,
        max:15
    ,
    lastname:
    
        type:String,
        require: true,
        trim:true,
        min:3,
        max:15
    ,
    email:
        type:String,
        require: true,
        trim:true,
        unique:true,
        lowercase:true
    ,
    contact:
        type:String,
        require: true,
        unique:true
    ,
    hash_password:
        type:String,
        require:true
    ,
    profile_picture:
    
        type:String
    ,
    status:
    
        type:Boolean,
        default:1
    
, timestamps:true );

partnerSchema.virtual('password')
.set(function(password)
    this.hash_password=bcrypt.hashSync(password, 10);
);

module.exports=mongoose.model("Partner",partnerSchema)

place.js

const mongoose=require('mongoose')

const placeSchema=mongoose.Schema(
    partner_id:
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Partner'
    ,
    title:
        type:String,
        require:true,
        trim:true,
        unique:true,
        lowercase:true,
        min:3,
        max:15
    ,
    city:
        type:String,
        require: true,
        lowercase:true
    ,
    state:
        type:String,
        require: true,
        lowercase:true
    ,
    country:
        type:String,
        require: true,
        lowercase:true
    ,
    pincode:
        type:String,
        require: true
    ,
    category:
        type:String,
        require: true,
        lowercase:true
    ,
    sub_category:
        type:String,
        require: true,
        lowercase:true
    ,
    description:
        type:String,
        require: true,
        lowercase:true
    ,
    address:
        type:String,
        require: true,
        lowercase:true
    ,
    nearest_railway_station:
        type:String,
        require: true,
        lowercase:true
    ,
    nearest_airport:
        type:String,
        require: true,
        lowercase:true
    ,
    image:
        type:String,
        require: true,
    ,
    Product_sale:
        type:Boolean,
        default:0
    ,
    status:
        type:Boolean,
        default:0
    
,timestamps:true)

module.exports=mongoose.model('Place',placeSchema);

index.js

const express= require('express');
const http= require('http');
const mongoose=require('mongoose');
var Passport = require('passport').Passport,
    passport = new Passport(),
    partnerPassport = new Passport();

const app= express();

app.use(passport.initialize());
app.use(partnerPassport.initialize());

const hostname = 'localhost';
const port = 2000;
const url="mongodb://localhost:27017"

mongoose.connect(
    'mongodb://localhost:27017/susvagatam', 
    
        useNewUrlParser: true,
        useUnifiedTopology: true,
        useCreateIndex: true,
        useFindAndModify:false
    
).then(()=>
    console.log('database connected');
);

const partnerRouter = require('./route/partnerRouter.js');
const usersRouter = require('./route/usersRouter.js');


app.use('/partners', partnerRouter);
app.use('/users', usersRouter);


const server= http.createServer(app)
server.listen(port,hostname,()=>
    console.log('server is runing')
);

如果我只添加合作伙伴那么工作正常,或者如果我只添加用户那么也工作正常。但是当同时添加它时它不能正常工作。回应未经授权。

一次认证可以正常工作,但两次认证不工作。

【问题讨论】:

【参考方案1】:

您在这里需要的是authorization,而不是authentication

verifyUser 处理身份验证,而verifyPartner 只处理合作伙伴的授权。

重构你的verifyPartner 看起来像这样:

module.exports.verifyPartner = (req, res, done) => 
  Partner.findOne( _id: req.params.partnerid , (err, partnerdata) => 
    if (err) 
      return done(err, false);
    

    if (partnerdata) 
      return done(null, partnerdata);
    

    return done(null, false);
  );
;

'/places/:partnerid' 路由上,您将其用作中间件,请确保在verifyPartner 之前先调用verifyUser

像这样:

partnerRouter.route('/places/:partnerid')
  .get(auth.verifyUser, auth.verifyPartner, (req,res,next)=> ...)

通过这种方式进行身份验证,首先验证user,然后再继续检查用户是否是授权合作伙伴。

【讨论】:

我正在按照您提供的解决方案更新我的代码,但它不适用于合作伙伴登录。它是返回未授权。对于单一身份验证,其返回 无法读取未定义的属性“_id”。我更新的代码是:auth.js module.exports.verifyUser = passport.authenticate('jwt', session: false); module.exports.verifyPartner = (req, res, done) => ...; partnerRoute.js partnerRouter.route('/places/:partnerid') .get(auth.verifyUser,auth.verifyPartner,(req,res,next)=>...)

以上是关于如何在单个快速路由 User.route('/').get((req,res,next)=> ) 上添加两个身份验证?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel Route 模型与关系绑定

如何使用 JWT 在 Express 中验证单个路由(无代码重复)的多种类型用户的身份验证令牌?

Vue Router 嵌套路由

Laravel 查询构建器与 where 左外连接

如何在 laravel 的单个控制器中传递多个路由

如何在不重写所有路由的情况下禁用 Express 中单个路由的 CORS?