Node.js - JWT,API:如何实现多护照.js身份验证中间件?



所以我正在尝试为一个应用程序构建两个 JWT 身份验证系统。一个用于用户,一个用于企业。身份验证使用护照(本地和 JWT(。我开始研究身份验证的用户方面,我能够让它按照我想要的方式工作。我以为商业也是如此。我所做的只是简单地复制粘贴并更改几个变量。通常,业务端点应该可以工作,但它不起作用。所以我试图调试正在发生的事情,我仍在试图弄清楚它是什么。我的猜测是,当我在应用程序中加载策略时.js,只会调用用户的护照策略。如果我在passportbusiness-passport之间排列位置,一切都会中断。

这是我的代码。

用户护照的护照中间件.js

const passport = require('passport');
const JwtStrategy = require('passport-jwt').Strategy;
const {ExtractJwt} = require('passport-jwt');
const LocalStrategy = require('passport-local').Strategy;
const { JWT_SECRET } = require('./config');
const User = require('./models/user');
// const Business = require('./models/business');
passport.use(new JwtStrategy({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: JWT_SECRET,
passReqToCallback: true
}, async (req, payload, done) => {
console.log('payload', payload)
try {
// Find the user specified in token
const user = await User.findById(payload.sub);
// Handle if User dont exist
if (!user) {
return done(null, false);
}
// Otherwise, return the user
req.user = user;
done(null, user);
} catch (error) {
done(error, false);
}
}));
// Local Strategy
passport.use(new LocalStrategy({
usernameField: 'email'
}, async (email, password, done) => {
try {
// Find the user given the email
const user = await User.findOne({email});
// If not, handle it
if (!user) {
return done(null, false);
}
// check if password is correct
const isMatch = await user.isValidPassword(password);
// if not, handle it
if (!isMatch) {
return done(null, false);
}
// Otherwise, return the user
done(null, user);
} catch (error) {
done(error, false);
}
}));

商务护照商务护照中间件.js

只需更改业务用户

用户控制器/用户的控制器.js

const fs = require('fs');
const mongoose = require('mongoose');
const JWT = require('jsonwebtoken');
const { JWT_SECRET } = require('../config');
const User = require('../models/user');
signToken = user => {
// Respond with token
return JWT.sign({
iss: 'My Business, Inc.',
userType: 'users',
sub: user._id, /* You can also use newUser.id */
iat: new Date().getTime(), /* Current Time */
exp: new Date().setDate(new Date().getDate() + 1), /* Current Time + 1 day ahead */
}, JWT_SECRET);
};
module.exports = {
signup: async (req, res, next) => {
console.log('req.value.body', req.value.body);
const {email, password} = req.value.body;
// Check if User already exist by email address
const foundUser = await User.findOne({email});
if(foundUser) {
return res.status(403).json({error: 'Email is already in use'});
}
// Create a new User
const newUser = new User({email, password});
await newUser.save();
// Generate the token
const token = signToken(newUser);
// Respond with token
res.status(200).json({token});
},
signin: async (req, res, next) => {
// Generate token
const token = signToken(req.user);
res.status(200).json({token});
// console.log('signin');
},
};

我之所以有req.value...,是因为中间件我用来验证我的身体和 url 参数

。 业务控制者/业务控制器.js . 一切都是一样的,只是用业务更改用户。

我还应该指出,每当我使用 jwt.io 查看我的令牌签名是否有效时,它总是说invalid signature,但一切都按预期在我的应用程序上运行。想知道为什么它说invalid signature.

用户的路由路由/用户.js .请记住,企业也是如此。

const express = require('express');
// this router deals better with "try{} catch{}" situations"
const router = require('express-promise-router')();
const passport = require('passport');
const UserController = require('../controllers/user');
require('../passport');
const { validateBody, schemas, validateParam } = require('../helpers/route-helpers');
const StrategyLocal = passport.authenticate('local', {session: false});
const StrategyJWT = passport.authenticate('jwt', {session: false});
router.get('/', (req, res) => {
res.json({message: "Welcome to our User's API Endpoint!"});
});
router.route('/signup')
// .get(UserController.index)
.post([validateBody(schemas.authSchema)], UserController.signup);
router.route('/signin')
// Makes sense to implement localstrat here because jWt will always work because the user was issued a token at signup
// So both solutions will work here as a strategy
.post(validateBody(schemas.authSchema), StrategyLocal, UserController.signin);
module.exports = router;   

最后,我认为导致问题的文件...正在推出。。。
应用.js

const express = require('express');
const logger = require('morgan');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const passport = require('passport');
const path = require('path');
const cors = require('cors');
const { dbName } = require('./config');
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost/' + dbName, {
useNewUrlParser:true,
useUnifiedTopology:true,
useCreateIndex: true,
useFindAndModify: false
});
const app = express();
// 👇👇👇👇 This is where the problem is happening in my opinion
require('./passport-business')
require('./passport')

const user = require('./routes/user');
const business = require('./routes/business');
// Middlewares
// set the static files location /public/img will be /img for users
app.use(logger('dev'));
app.use(cors());
app.use(bodyParser.urlencoded({ extended: false}));
app.use(bodyParser.json());
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, noauth");
if (req.method === 'OPTIONS'){
res.header("Access-Control-Allow-Methods", "PUT, POST, PATCH, DELETE, OPTIONS");
res.setHeader('Access-Control-Allow-Credentials', false);
return res.status(200).json({});
}
next();
});
app.use('/api/users', user);
app.use('/api/businesses', business);

// Start the server
const port =  app.get('port') || 2019;
app.listen(port, () => console.log(`Server is listening on port ${port}`));

如果我保持一切正常,所有用户终结点都可以工作,注册适用于企业,但在尝试登录(企业(时收到 401。但是如果我这样做...

require('./passport')
require('./passport-business')    

尝试登录时收到401(用户(,尝试登录时收到 500(企业(。
有人可以告诉我我在这里做错了什么吗?也许这是我在app.js中加载这些文件的顺序。也许是我正在为用户和业务创建两个单独的passport文件。我很想知道如何将这两者合二为一。.

所以在passport.js中你这样做:

try {
// Find the user specified in token
const user = await User.findById(payload.sub);
// Handle if User dont exist
if (!user) {
return done(null, false);
}
// Otherwise, return the user
req.user = user;
done(null, user);
} catch (error) {
done(error, false);
}

您不能userType您已经登录到 JWT 并制定条件吗?

即:

try {
// Find the user specified in token
let user = null;
if (payload.userType === 'user') {
user = await User.findById(payload.sub);
}
if (payload.userType === 'business') {
user = await Business.findById(payload.sub);
}
// Handle if User dont exist
if (!user) {
return done(null, false);
}
// Otherwise, return the user
req.user = user;
done(null, user);
} catch (error) {
done(error, false);
}

然后,如果您需要两个护照文件,则只需要一个

最新更新