0

我是 JWT 和 Passport 的新手,所以我开始关注 NoobCoder 在 Youtube 上的 MERN 教程,该教程涉及使用 JWT 进行身份验证和授权。我到达了路由处理'/logout'的部分,我得到了邮递员的答复未经授权。到目前为止的代码看起来完全一样。有人可以帮我理解这里有什么问题吗?

我已将代码附在底部。如果需要更多信息,请告诉我。

这是代码:

应用程序.js

const express = require('express');
const app = express();
const cookieParser = require('cookie-parser');
const mongoose = require('mongoose');
app.use(cookieParser());
app.use(express.json());

mongoose.connect('mongodb://localhost:27017/mernauth', {useNewUrlParser: true, useUnifiedTopology: true}, () => {
   



console.log('Successfully connected to DB');
});

const userRouter = require('./routes/User');
app.use('/user', userRouter);

app.listen(5000, () => {
    console.log('express server started');
});

护照.js

const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const JwtStrategy = require('passport-jwt').Strategy;
const User = require('./models/User');

const cookieExtractor = req => {
    let token = null;
    if(req && req.cookies) {
        token = req.cookies['access_token'];
    }
    return token;
}

// Authorization
passport.use(new JwtStrategy({
    jwtFromRequest: cookieExtractor,
    secretOrKey: 'NoobCoder'
}, (payload, done) => {
    User.findById({_id: payload.sub}, (err, user) => {
        if(err) {
            return done(err, false);
        }
        if(user) {
            return done(null, user);
        }
        else {
            return done(null, false);
        }
    })
}));

// Authenticated local strategy using username and password
passport.use(new LocalStrategy((username, password, done) => {
    User.findOne({username}, (err, user) => {
        // Something went wrong with DB
        if(err) {
            return done(err);
        }

        // If no user exists; null = no error; false = user does not exist
        if(!user) {
            return done(null, false);
        }

        // Check if password is correct; callback cb = done
        user.comparePassword(password, done);
    });
}));

User.js(路由)

const express = require('express');
const userRouter = express.Router();
const passport = require('passport');
const passportConfig = require('../passport');
const JWT = require('jsonwebtoken');
const User = require('../models/User');
const Todo = require('../models/Todo');

const signToken = userID => {
    return JWT.sign({
        iss: "NoobCoder",
        sub: userID
    }, "NoobCoder", {expiresIn: "1h"});
}

userRouter.post('/register', (req, res) => {
    const {username, password, role} = req.body;
    User.findOne({username}, (err, user) => {
        if(err) {
            res.status(500).json({message: {msgBody: "Error has occured", msgError: true}})
        }
        if(user) {
            res.status(400).json({message: {msgBody: "Username is already taken", msgError: true}})
        }
        else {
            const newUser = new User({username, password, role});
            newUser.save(err => {
                if(err) {
                    res.status(500).json({message: {msgBody: "Error has occured", msgError: true}})
                }
                else {
                    res.status(201).json({message: {msgBody: "Account Successfully Created", msgError: false}})
                }
            })
        }
    })
});

userRouter.post('/login', passport.authenticate('local', {session: false}), (req, res) => {
    if(req.isAuthenticated()) {
        const {_id, username, role} = req.user;
        const token = signToken(_id);
        res.cookie('access_token', token, {httpOnly: true, sameSite: true});
        res.status(200).json({isAuthenticated: true, user: {username, role}})
    }
});

userRouter.get('/logout', passport.authenticate('jwt', {session: false}), (req, res) => {
    res.clearCookie('access_token');
    res.json({user: {username: '', role: ''}, success: true});
});

module.exports = userRouter;

User.js(模型)

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

const UserSchema = new mongoose.Schema({
    username: {
        type: String,
        required: true,
        min: 6,
        max: 15
    },
    password: {
        type: String,
        required: true,
    },
    role: {
        type: String,
        enum: ['user', 'admin'],
        required: true
    },
    todos: [{type: mongoose.Schema.Types.ObjectId, ref: 'Todo'}]
});

UserSchema.pre('save', function(next) {
    if(!this.isModified('password')) {
        return next()
    }

    bcrypt.hash(this.password, 10, (err, passwordHash) => {
        if(err) {
            return next(err);
        }

        this.password = passwordHash;
        next();
    });
});

UserSchema.methods.comparePassword = function(password, cb) {
    bcrypt.compare(password, this.password, (err, isMatch) => {
        if(err) {
            return cb(err);
        }
        else {
            if(!isMatch) {
                return cb(null, isMatch)
            }
            return cb(null, this);
        }
    })
};

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

2 回答 2

0

也许/logout由于 JWT 令牌不存在,该路由是未经授权的?

可以通过确保cookieExtractor函数返回令牌来验证 JWT 令牌的存在

于 2021-03-12T13:36:49.253 回答
-2
app.get('/logout', function(req, res){
  req.logout();
  res.redirect('/');
});

资源

于 2020-10-04T12:10:58.977 回答