浏览器中的护照身份验证缺少凭据

Passport authentication missing credentials in browser

我正在学习如何使用 passport.js. I have a basic passport "local" strategy set up on the server side and so far just a single POST route to log a user in. This all works exactly as intended when troubleshooting with insomnia 实现用户身份验证,但是当我从浏览器发出相同的请求时,我收到一条消息 missing credentials。此消息来自 controllers/auth.js.

中的 console.log(info)

我已尝试在提取请求中包含凭据,如下所示,但我一定是遗漏了其他内容或错误地包含了它们。我还将变量名从 'email' 更改为 'username' 因为我读到这是 passport.js.

的默认值

根据我在 Chrome 开发工具中的了解,请求正文的格式正确,我正在访问正确的端点。

controllers/auth.js

const express = require("express");
const router = express.Router();
const passport = require("passport");

router.post("/register_login", (req, res, next) => {
    passport.authenticate("local", function(err, user, info) {
        console.log(info)
        if (err) {
            return res.status(400).json({ errors: err });
        }
        if (!user) {
            return res.status(400).json({ errors: "No user found" });
        }
        req.logIn(user, function(err) {
            if (err) {
                return res.status(400).json({ errors: err });
            }
            return res.status(200).json({ success: `logged in ${user.id}` });
        });
    })(req, res, next);
});

module.exports = router;

passport/setup.js

const bcrypt = require('bcrypt');
const { User } = require('../models');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;

passport.serializeUser((user, done) => {
    done(null, user.id);
});

passport.deserializeUser((id, done) => {
    User.findById(id, (err, user) => {
        done(err, user);
    });
});

// Local Strategy
passport.use(new LocalStrategy((username, password, done) => {
        // Match User
        User.findOne({ email: username })
            .then(user => {
                // Create new User
                if (!user) {
                    return done(null, false, { message: 'No user found!!'})
                    // Return other user
                } else {
                    // Match password
                    bcrypt.compare(password, user.password, (err, isMatch) => {
                        if (err) throw err;

                        if (isMatch) {
                            return done(null, user);
                        } else {
                            return done(null, false, { message: 'Wrong password' });
                        }
                    });
                }
            })
            .catch(err => {
                return done(null, false, { message: err });
            });
    })
);

module.exports = passport;

客户端获取

const handleLogin = async (evt) => {
    evt.preventDefault();
    const response = await fetch('/auth/register_login', {
        method: 'POST',
        credentials: 'include',
        withCredentials: true,
        body: JSON.stringify({
            "username": "test@email.com",
            "password": "password"
        })
    })
    return response;
};

哦,这是一个简单的...

我在 Chrome 开发工具中阅读“Content-Type”,但我在阅读“响应 Headers”时认为它们是“请求 Headers”。问题是我发送的是文本而不是 json.

将客户端提取更改为下面的代码片段解决了该问题。

客户端获取

const handleLogin = async (evt) => {
    evt.preventDefault();
    const response = await fetch('/auth/register_login', {
        method: 'POST',
        credentials: 'include',
        withCredentials: true,
        headers: {
            'Content-Type': 'application/json' // <--add this
        body: JSON.stringify({
            "username": "test@email.com",
            "password": "password"
        })
    })
    return response;
};