首页 > 解决方案 > 为什么我的 Express.js 在使用 auth 中间件时表现不一致?

问题描述

我有一个 Express.js 后端服务器,它提供一个公共登录页面和我的私人反应应用程序。

我的问题是我的快速服务器的身份验证行为不一致。有了这个我定位在这篇文章:https ://stackoverflow.com/a/21341538/4908844

我基本上有三种路线:

http://localhost:4000-> 私人的

http://localhost:4000/login/-> 公开

http://localhost:4000/api/auth/-> 公开

整个中间件代码可以在底部找到。

当我没有登录时,一切正常(没有可用的带有 jwt 令牌的 auth-cookie)。如果我尝试输入http://localhost:4000,我会收到以下控制台输出:

Logged  /  GET -- Fri Dec 11 2020 09:52:26 GMT+0100 (GMT+01:00)
undefined
{ JsonWebTokenError: jwt must be provided
    at Object.module.exports [as verify] (C:\Users\Development\apps\backend\node_modules\jsonwebtoken\verify.js:53:17)
    at C:\Users\Development\apps\backend\server.js:90:9
    at Layer.handle [as handle_request] (C:\Users\Development\apps\backend\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (C:\Users\Development\apps\backend\node_modules\express\lib\router\index.js:317:13)
    at C:\Users\Development\apps\backend\node_modules\express\lib\router\index.js:284:7
    at Function.process_params (C:\Users\Development\apps\backend\node_modules\express\lib\router\index.js:335:12)
    at next (C:\Users\Development\apps\backend\node_modules\express\lib\router\index.js:275:10)
    at cookieParser (C:\Users\Development\apps\backend\node_modules\cookie-parser\index.js:71:5)
    at Layer.handle [as handle_request] (C:\Users\Development\apps\backend\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (C:\Users\Development\apps\backend\node_modules\express\lib\router\index.js:317:13) name: 'JsonWebTokenError', message: 'jwt must be provided' }
redirect triggered
Logged  /login/  GET -- Fri Dec 11 2020 09:52:26 GMT+0100 (GMT+01:00)

代码正确地看到没有 jwt 令牌并且无法验证它 - 所以它重定向回/login/

代码在这里:

app.use(function (req, res, next) {

    // check for token cookie

    const authCookie = req.cookies["auth-cookie"];
    console.log(authCookie)

    // check jwt token jwt.verify
    jwt.verify(authCookie, jwtSecret, (err, decoded) => {
        // if token is valid
        if (decoded) {
            console.log("valid token")
            next();
        }
        // if token is invalid
        if (err) {
            console.log(err)
            console.log("redirect triggered")
            res.redirect('/login');
        }
    })
});

如果我使用正确的用户名和密码登录,我会得到一个带有 jwt 的 http 'auth-cookie'。如果我再次尝试相同的操作(输入 http://localhost:4000 - 见上文),我会收到以下输出:

Logged  /  GET -- Fri Dec 11 2020 09:57:20 GMT+0100 (GMT+01:00)
eyJhbG... (rest of token)
valid token
Logged  /static/css/main.d92f8d30.chunk.css  GET -- Fri Dec 11 2020 09:57:20 GMT+0100 (GMT+01:00)
eyJhbG... (rest of token)
valid token
Logged  /static/js/2.77090840.chunk.js  GET -- Fri Dec 11 2020 09:57:20 GMT+0100 (GMT+01:00)
eyJhbG... (rest of token)
valid token
Logged  /static/js/main.af5d173b.chunk.js  GET -- Fri Dec 11 2020 09:57:20 GMT+0100 (GMT+01:00)
eyJhbG... (rest of token)
valid token
Logged  /static/css/main.d92f8d30.chunk.css.map  GET -- Fri Dec 11 2020 09:57:20 GMT+0100 (GMT+01:00)
eyJhbG... (rest of token)
valid token
Logged  /static/js/2.77090840.chunk.js.map  GET -- Fri Dec 11 2020 09:57:20 GMT+0100 (GMT+01:00)
eyJhbG... (rest of token)
valid token
Logged  /locales/en/translation.json  GET -- Fri Dec 11 2020 09:57:21 GMT+0100 (GMT+01:00)
eyJhbG... (rest of token)
valid token
Logged  /static/js/main.af5d173b.chunk.js.map  GET -- Fri Dec 11 2020 09:57:21 GMT+0100 (GMT+01:00)
eyJhbG... (rest of token)
valid token
Logged  /static/media/Logo.8a7963fc.png  GET -- Fri Dec 11 2020 09:57:21 GMT+0100 (GMT+01:00)
eyJhbG... (rest of token)
valid token
Logged  /static/media/infButtonHome.e2ebb5ae.png  GET -- Fri Dec 11 2020 09:57:21 GMT+0100 (GMT+01:00)
eyJhbG... (rest of token)
valid token
Logged  /static/media/indButtonHome.c3a23e56.png  GET -- Fri Dec 11 2020 09:57:21 GMT+0100 (GMT+01:00)
eyJhbG... (rest of token)
valid token
Logged  /static/media/evuButtonHome.7761c048.png  GET -- Fri Dec 11 2020 09:57:21 GMT+0100 (GMT+01:00)
eyJhbG... (rest of token)
valid token
Logged  /locales/de/translation.json  GET -- Fri Dec 11 2020 09:57:21 GMT+0100 (GMT+01:00)
eyJhbG... (rest of token)
valid token
Logged  /  GET -- Fri Dec 11 2020 09:57:21 GMT+0100 (GMT+01:00)
eyJhbG... (rest of token)
valid token
Logged  /static/media/homeBackground.3b448d30.png  GET -- Fri Dec 11 2020 09:57:21 GMT+0100 (GMT+01:00)
eyJhbG... (rest of token)
valid token
Logged  /cookie.png  GET -- Fri Dec 11 2020 09:57:21 GMT+0100 (GMT+01:00)
eyJhbG... (rest of token)
valid token
Logged  /static/media/ecosystem.1c470787.png  GET -- Fri Dec 11 2020 09:57:21 GMT+0100 (GMT+01:00)
eyJhbG... (rest of token)
valid token
Logged  /manifest.json  GET -- Fri Dec 11 2020 09:57:21 GMT+0100 (GMT+01:00)
undefined
{ JsonWebTokenError: jwt must be provided
    at Object.module.exports [as verify] (C:\Users\Development\apps\backend\node_modules\jsonwebtoken\verify.js:53:17)
    at C:\Users\Development\apps\backend\server.js:90:9
    at Layer.handle [as handle_request] (C:\Users\Development\apps\backend\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (C:\Users\Development\apps\backend\node_modules\express\lib\router\index.js:317:13)
    at C:\Users\Development\apps4ioe_pwa\backend\node_modules\express\lib\router\index.js:284:7
    at Function.process_params (C:\Users\Development\apps\backend\node_modules\express\lib\router\index.js:335:12)
    at next (C:\Users\Development\apps4ioe_pwa\backend\node_modules\express\lib\router\index.js:275:10)
    at cookieParser (C:\Users\Development\apps\backend\node_modules\cookie-parser\index.js:57:14)
    at Layer.handle [as handle_request] (C:\Users\Development\apps\backend\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (C:\Users\Development\apps\backend\node_modules\express\lib\router\index.js:317:13) name: 'JsonWebTokenError', message: 'jwt must be provided' }
redirect triggered
Logged  /login/  GET -- Fri Dec 11 2020 09:57:21 GMT+0100 (GMT+01:00)

eyJhbG... (rest of token)实际上是我出于隐私原因而缩短的正确且有效的令牌。

为什么代码执行15次正常并且cookie正确传输但最后一次在

Logged  /manifest.json  GET -- Fri Dec 11 2020 09:57:21 GMT+0100 (GMT+01:00)
undefined

我收到了一个以前一直存在的未定义的 jwt?

另外为什么我会收到重定向的日志

redirect triggered
Logged  /login/  GET -- Fri Dec 11 2020 09:57:21 GMT+0100 (GMT+01:00)

但它没有执行重定向?我的浏览器还在http://localhost:4000

这也是我完整的中间件代码:

// custom middleware create
const LoggerMiddleware = (req, res, next) =>{
    console.log(`Logged  ${req.url}  ${req.method} -- ${new Date()}`)
    next();
}

app.use(LoggerMiddleware);

app.use(cors({
    origin: [
        'http://localhost:3000',
    ],
    credentials: true,
}))
app.use(cookieParser());
app.use('/login/', express.static('public'))
app.use(function (req, res, next) {

    // check for token cookie

    const authCookie = req.cookies["auth-cookie"];
    console.log(authCookie)
    //console.log(cookies.search("auth-cookie"))
    //const authCookie = cookies.substring

    // get content of the auth cookie
    // check jwt.verify
    jwt.verify(authCookie, jwtSecret, (err, decoded) => {
        // if token is valid
        if (decoded) {
            console.log("valid token")
            next();
        }
        // if token is invalid
        if (err) {
            console.log(err)
            console.log("redirect triggered")
            res.redirect('/login');
        }
    })
});

app.use(express.static(path.join(__dirname, 'build/app')))

app.listen(port, () => {
    console.log(`Example app listening at http://localhost:${port}`)
})

有什么想法,为什么我的代码会这样?为什么 jwt 令牌突然出现undefined在末尾,如果确实如此,为什么我不像开始时那样没有 jwt 得到重定向?

谢谢!

编辑: auth-cookie 使用以下代码设置

app.get('/api/auth/', function (req, res) {
    // auth header is available
    if (req.headers.authorization) {
        // getting auth header and decoding it for user and password
        const base64encodedAuth = req.headers.authorization.substring(6);
        const encodedAuth = Buffer.from(base64encodedAuth, 'base64').toString('ascii');
        const user = encodedAuth.substring(0, encodedAuth.indexOf(":"));
        const password = encodedAuth.substring(encodedAuth.indexOf(":") + 1);

        // checking if user with correct password exists and return auth-cookie if he does
        if (user in users) {
            console.log("user exists")
            if (users[user] === password) {
                console.log("authenticated!")

                const jwtPayload = {
                    "user": user
                }

                const token = jwt.sign(jwtPayload, jwtSecret)

                res.cookie('auth-cookie', token, {
                    maxAge: 600000,
                    httpOnly: true
                });
                res.sendStatus(200)
            }
            else {
                console.log("wrong password")
                res.sendStatus(401)
            }
        }
        else {
            console.log("wrong user name")
            res.sendStatus(401)
        }
    }
    // no auth header available
    else {
        res.sendStatus(400)
    }
})

正如 Molda 在评论中暗示的那样,我检查了 DevTools/Network 选项卡。对于该manifest.json文件,没有 cookie 标签

在此处输入图像描述

标签: node.jsreactjsrestexpressjwt

解决方案


推荐阅读