NodeJS 尝试重定向到其他路由时发生Express 404错误

juud5qan  于 2023-02-15  发布在  Node.js
关注(0)|答案(1)|浏览(123)

我尝试在Postman中测试Express服务器,但收到404 Not found错误。当我尝试通过/users/demoLogin登录我的演示用户帐户时,出现此错误。

POST /users/demoLogin 302 93.222 ms - 30
Executing (default): SELECT "id", "firstName", "lastName", "email", "hashedPassword", "createdAt", "updatedAt" FROM "Users" AS "User" WHERE "User"."id" = 1;
NotFoundError: Not Found
    at /home/jas0123/noted/noted-api/app.js:48:8
    at Layer.handle [as handle_request] (/home/jas0123/noted/noted-api/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/home/jas0123/noted/noted-api/node_modules/express/lib/router/index.js:328:13)
    at /home/jas0123/noted/noted-api/node_modules/express/lib/router/index.js:286:9
    at Function.process_params (/home/jas0123/noted/noted-api/node_modules/express/lib/router/index.js:346:12)
    at next (/home/jas0123/noted/noted-api/node_modules/express/lib/router/index.js:280:10)
    at /home/jas0123/noted/noted-api/node_modules/express/lib/router/index.js:646:15
    at next (/home/jas0123/noted/noted-api/node_modules/express/lib/router/index.js:265:14)
    at Function.handle (/home/jas0123/noted/noted-api/node_modules/express/lib/router/index.js:175:3)
    at router (/home/jas0123/noted/noted-api/node_modules/express/lib/router/index.js:47:12)
GET /users/1 404 7.878 ms - 33

当我在404错误之前记录请求对象时,我看到:

url: '/users/1',
method: 'GET',

对象内,因此它看起来指向路线。
这是我的app. js

const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const { sequelize } = require('./db/models');
const session = require('express-session');
const SequelizeStore = require('connect-session-sequelize')(session.Store);
const usersRouter  = require('./routes/users');
const { restoreUser } = require('./auth');
const { sessionSecret } = require('./config');
const app = express();

app.use(session({
  name: 'noted.sid',
  secret: sessionSecret,
  resave: false,
  saveUninitialized: false
}));

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());

// set up session middleware
const store = new SequelizeStore({ db: sequelize });

app.use(
  session({
    secret: 'superSecret',
    store,
    saveUninitialized: false,
    resave: false,
  })
);

// restore user middleware
app.use(restoreUser);

// create Session table if it doesn't already exist
store.sync();

app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
  console.log(req);
  next(createError(404));
});

// error handler
app.use(function (err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  console.log(err)
  res.json({error: err});
});

module.exports = app;

这些是我的用户路径

const express = require('express');
const { check, validationResult } = require('express-validator');
const bcrypt = require('bcryptjs');
const {csurfProtection, asyncHandler} = require('./utils')
const db = require('../db/models');
const { loginUser, logoutUser } = require('../auth');
const router = express.Router();
if(process.env.NODE_ENV === 'production') router.use(csurfProtection)

// Validations middleware
const signupValidation = [
  check("firstName")
    .exists({ checkFalsy: true })
    .withMessage('Please provide a value for First Name')
    .isLength({ max: 50})
    .withMessage('First Name must not be more than 50 characters long'),
  check("lastName")
    .exists({ checkFalsy: true })
    .withMessage('Please provide a value for Last Name')
    .isLength({ max: 50})
    .withMessage('First Name must not be more than 50 characters long'),
  check("email")
    .exists({ checkFalsy: true })
    .withMessage('Please provide a value for Email Address')
    .isLength({ max: 150})
    .withMessage('Email address must not be more than 255 characters long'),
  check("password")
    .exists({ checkFalsy: true })
    .withMessage('Please provide a value for password')
    .isLength({ max: 50})
    .withMessage('Password must not be more than 50 characters long')
    .matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*])(?=.{8,})/)
    .withMessage('Password should contain at least 1 lowercase letter, uppercase letter, number, and special character'),
  check("confirmPassword")
    .exists({ checkFalsy: true })
    .withMessage('Please confirm password')
    .custom((val, { req }) => val === req.body.password)
    .withMessage('Password and password confirm do not match'),

]

const loginValidation = [
  check("email")
    .exists({ checkFalsy: true })
    .withMessage('Please provide a value for Email Address'),

  check("password")
    .exists({ checkFalsy: true })
    .withMessage('Please provide a value for password')
]



/* GET user */
router.get('/:id(\d+)', asyncHandler(async function(req, res, next) {
  console.log("Hit this route!")
  const learningStacks = await db.LearningStack.findAll({ where: { userID: req.params.id, } });
  return res.json({user: res.locals.user.dataValues, learningStacks})
}));



router.get("/signup", csurfProtection, function(req, res, next) {
  const csrfToken = req.csrfToken()
  res.json({csrfToken, user: {}});
})

router.post("/signup",  signupValidation, asyncHandler(async function(req, res) {
  const errors = validationResult(req).errors.map(e => e.msg);

  // create user object with fields to re-render if there are errors
  const prefillUser = db.User.build({
      email: req.body.email,
      firstName: req.body.firstName,
    });

  if (errors.length > 0) {
    return res.json({ user: prefillUser, errors, csrfToken: req.csrfToken()});
  } else {

    // check if the e-mail is available
    emailPresent = await db.User.count( { where: { email: req.body.email } })
    if (emailPresent) {
      errors.push("A user with this e-mail already exists.")
      return res.json({ user: prefillUser, errors, csrfToken: req.csrfToken()});
    }

    const saltRounds = 10;
    const salt = await bcrypt.genSalt(saltRounds);
    const hashedPassword = await bcrypt.hash(req.body.password, salt);

    const user = await db.User.create({
      email: req.body.email,
      firstName: req.body.firstName,
      lastName: req.body.lastName,
      hashedPassword,
    });

    loginUser(req, res, user);
    return res.redirect(req.session.redirectTo || "/")
  }

}));

router.post('/login',  loginValidation, asyncHandler (async (req, res, next) =>{

  const errors = validationResult(req).errors.map(e => e.msg);

  if (errors.length > 0) {
    return res.json( {errors, csrfToken: req.csrfToken()});}
  else {
    const user = await db.User.findOne({ where: { email: req.body.email } });
    if (user) {
      const isPasswords = await bcrypt.compare(
        req.body.password,
        user.hashedPassword.toString(),
      );
      if (isPasswords) {
        loginUser(req, res, user);
        return res.redirect(req.session.redirectTo ||`/users/1`);
      }
    }
  }
  errors.push("Email address or password incorrect.");
  return res.json({ errors, csrfToken: req.csrfToken() });
}))

router.get('/login', csurfProtection,  (req, res, next) =>{
  return res.json({csrfToken: req.csrfToken()});
})

router.post('/logout', asyncHandler(async (req, res, next) => {
  logoutUser(req);
  return res.redirect(req.session.redirectTo || "/");
}))

router.post('/demoLogin', csurfProtection, loginValidation, asyncHandler (async (req, res, next) =>{

  errors=[]

    const user = await db.User.findOne({ where: { email: 'demo_noted_user@gmail.com' } });
    if (user) {
      const isPasswords = await bcrypt.compare(
        'Password1!',
        user.hashedPassword.toString(),
      );
      if (isPasswords) {
        loginUser(req, res, user);
        return res.redirect(req.session.redirectTo || "/users/1");
      }
    }
  
  errors.push("Demo login not found.");
  return res.json({ errors, csrfToken: req.csrfToken() });
}))

module.exports = router;

我在控制台中看不到console.log(“Hit this route!”)。我没有正确重定向吗?

const db = require('./db/models');

const loginUser = (req, res, user) => {
  req.session.auth = { userId: user.id }
}

const restoreUser = async (req, res, next) => {

  if (req.session.auth) {
    try {
      const { userId } = req.session.auth;
      const user = await db.User.findByPk(userId);
      if (user) {
        console.log(user, "user <-- THIS LOGS");
        res.locals.authenticated = true;
        res.locals.user = user;
        next();
        return 
      }
    } catch (e) {
      console.log(e, "THIS IS E")
      res.locals.authenticated = false;
      next(e);
      return
    }
  }
  res.locals.authenticated = false;
  next();
}

const logoutUser = (req, res) => {
  delete req.session.auth;
}

module.exports = {
  loginUser,
  restoreUser,
  logoutUser
}

这些是我的auth中间件

ar7v8xwq

ar7v8xwq1#

看起来您正在到达/users/1/users/:id)端点,但是,您将路由定义为router.get('/:id(\d+)',该路由缺少/users/前缀。
请尝试使用此:
router.get('/users/:id(\d+)'

相关问题