jsonwebtokenerror:jwt必须是字符串,node.js

发布于 2025-02-13 11:28:37 字数 5151 浏览 1 评论 0原文

我会遇到错误 jsonwebtokenerror:当从前端获得JWT(react.js)并在中间件中使用以验证令牌时,JWT必须是字符串。如果我试图使用tostring,它会给我另一个错误 jsonwebtokenerror:jwt畸形

更新

一旦我从前端传递访问权限后,它将其转换为authmiddleware.js中的对象。 如下)

标题上传递中间件(

const { verify } = require("jsonwebtoken")


const validateToken = (res, req, next) => {
    const accesToken = req.header("accesToken");
    const stringAccesToken = accesToken.toString()
    console.log(typeof (stringAccesToken), "accesToken type")

if (!stringAccesToken) {
    return res.json({ error: "user not logged in" })

}

try {
    const validToken = verify(stringAccesToken, "importantSecret");
    console.log(validToken, 'validtoken')
    if (validToken) {
        return next();
    }
} catch (err) {
    console.log(err, "error")
    }

}

module.exports = { validateToken }

我正在File Post.js

const express = require("express");
const router = express.Router()
const { Users } = require("../models")
const bcrypt = require("bcrypt")

const { sign } = require("jsonwebtoken")

  

router.post("/login", async (req, res) => {
    const { username, password } = req.body;
    const user = await Users.findOne({ where: { username: username } });

    if (!user) {
        return res.json({ error: "User dosen't exist" })
    }

    bcrypt.compare(password, user.password)
        .then((match) => {
            if (!match) {
                return res.json({ error: "Wrong Username and Password match" })
            }
            const accessToken = sign({ username: user.username, id: user.id }, "importantSecret")
            res.json(accessToken)
        })
})

module.exports = router;

中的 >

import React, { useEffect, useState } from 'react'
import { useParams } from 'react-router-dom';
import axios from 'axios';
import './Post.css'


function Post() {

    let { id } = useParams();

    const [postObject, setPostObject] = useState({})
    const [comments, setComments] = useState([]);
    const [newComment, setNewComment] = useState("");

    // console.log(comments)

    const addComment = () => {


        const accessToken = sessionStorage.getItem('accessToken')
        console.log(typeof (accessToken), 'acces token in comment button')

        axios.post(`http://localhost:4000/comments`,
            {
                commentBody: newComment,
                PostId: id
            },
            {
                headers: {
                    accessToken: sessionStorage.getItem("accessToken"),
                }
            }
        )
            .then((res) => {
                // console.log(res)
                const data = res.data;
                console.log(data, 'comments')

                setComments([...comments, data])
                setNewComment("")
            })
            .catch((err) => {
                alert(err, 'Error:comment')
            })
    }



    useEffect(() => {
        axios.get(`http://localhost:4000/posts/byId/${id}`)
            .then((res) => {
                // console.log(res)
                const data = res.data;
                // console.log(data)

                setPostObject(data)
                // setPost(data)

            })

        // comment api request
        axios.get(`http://localhost:4000/comments/${id}`)
            .then((res) => {
                // console.log(res)
                const data = res.data;
                // console.log(data)

                setComments(data)

            })
    }, [])


    return (
        <div className='Post'>

            <div className='left__side'>
                <div className='left__side__wrapper'>

                    <div className='title'>{postObject.title}</div>
                    <div className='text'>{postObject.postText}</div>
                    <div className='username'>{postObject.username}</div>
                </div>


            </div>
            <div className='right__side'>
                <div className='right__side__wrapper'>
                    <div className='add__comment__container'>

                        <input type="text"
                            value={newComment}
                            placeholder="Comment"
                            //  autoComplete="off"
                            onChange={(e) => setNewComment(e.target.value)}

                        />
                        <button onClick={addComment}> Submit Comment</button>

                    </div>
                    <div className='listOfCommnets'>

                        {comments.map((item, index) => {
                            {/* console.log(item, 'item') */ }
                            return <div className='comments' key={index}>Comments:<br />{item.commentBody}</div>

                        })}
                    </div>
                </div>
            </div>

        </div>
    )
}

export default Post

I'm getting the error JsonWebTokenError: jwt must be a string when getting the jwt from the front end (react.js) and using in middleware to verify the token. If I tried to use toString it gives me another error JsonWebTokenError: jwt malformed.

Update

As soon as i pass the accessToken from frontEnd it converted into object in the AuthMiddleware.js. I'm passing middleware on header in file Post.js(attached below)

AuthMiddleware.js

const { verify } = require("jsonwebtoken")


const validateToken = (res, req, next) => {
    const accesToken = req.header("accesToken");
    const stringAccesToken = accesToken.toString()
    console.log(typeof (stringAccesToken), "accesToken type")

if (!stringAccesToken) {
    return res.json({ error: "user not logged in" })

}

try {
    const validToken = verify(stringAccesToken, "importantSecret");
    console.log(validToken, 'validtoken')
    if (validToken) {
        return next();
    }
} catch (err) {
    console.log(err, "error")
    }

}

module.exports = { validateToken }

User.js (backend for login)

const express = require("express");
const router = express.Router()
const { Users } = require("../models")
const bcrypt = require("bcrypt")

const { sign } = require("jsonwebtoken")

  

router.post("/login", async (req, res) => {
    const { username, password } = req.body;
    const user = await Users.findOne({ where: { username: username } });

    if (!user) {
        return res.json({ error: "User dosen't exist" })
    }

    bcrypt.compare(password, user.password)
        .then((match) => {
            if (!match) {
                return res.json({ error: "Wrong Username and Password match" })
            }
            const accessToken = sign({ username: user.username, id: user.id }, "importantSecret")
            res.json(accessToken)
        })
})

module.exports = router;

Post.js

import React, { useEffect, useState } from 'react'
import { useParams } from 'react-router-dom';
import axios from 'axios';
import './Post.css'


function Post() {

    let { id } = useParams();

    const [postObject, setPostObject] = useState({})
    const [comments, setComments] = useState([]);
    const [newComment, setNewComment] = useState("");

    // console.log(comments)

    const addComment = () => {


        const accessToken = sessionStorage.getItem('accessToken')
        console.log(typeof (accessToken), 'acces token in comment button')

        axios.post(`http://localhost:4000/comments`,
            {
                commentBody: newComment,
                PostId: id
            },
            {
                headers: {
                    accessToken: sessionStorage.getItem("accessToken"),
                }
            }
        )
            .then((res) => {
                // console.log(res)
                const data = res.data;
                console.log(data, 'comments')

                setComments([...comments, data])
                setNewComment("")
            })
            .catch((err) => {
                alert(err, 'Error:comment')
            })
    }



    useEffect(() => {
        axios.get(`http://localhost:4000/posts/byId/${id}`)
            .then((res) => {
                // console.log(res)
                const data = res.data;
                // console.log(data)

                setPostObject(data)
                // setPost(data)

            })

        // comment api request
        axios.get(`http://localhost:4000/comments/${id}`)
            .then((res) => {
                // console.log(res)
                const data = res.data;
                // console.log(data)

                setComments(data)

            })
    }, [])


    return (
        <div className='Post'>

            <div className='left__side'>
                <div className='left__side__wrapper'>

                    <div className='title'>{postObject.title}</div>
                    <div className='text'>{postObject.postText}</div>
                    <div className='username'>{postObject.username}</div>
                </div>


            </div>
            <div className='right__side'>
                <div className='right__side__wrapper'>
                    <div className='add__comment__container'>

                        <input type="text"
                            value={newComment}
                            placeholder="Comment"
                            //  autoComplete="off"
                            onChange={(e) => setNewComment(e.target.value)}

                        />
                        <button onClick={addComment}> Submit Comment</button>

                    </div>
                    <div className='listOfCommnets'>

                        {comments.map((item, index) => {
                            {/* console.log(item, 'item') */ }
                            return <div className='comments' key={index}>Comments:<br />{item.commentBody}</div>

                        })}
                    </div>
                </div>
            </div>

        </div>
    )
}

export default Post

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

月朦胧 2025-02-20 11:28:37

由于JWT令牌将对象用作输入而不是使用“验证”一词,因此它不再与您接收错误的对象一起使用。相反,您必须尝试以下尝试。

var jwt = require("jsonwebtoken");

const validateToken = (res, req, next) => {
const accesToken = req.header("accesToken");
const stringAccesToken = accesToken;

if (!stringAccesToken) {
   return res.json({ error: "user not logged in" });
}

jwt.verify(stringAccesToken, "importantSecret", function (err, decoded) {
  if (err)
    return console.log(err)
  // Next Code
  next();
 });
};

module.exports = { validateToken };

Because the jwt token is using an object as an input rather than using the word "verify," it won't work with the object in which you are receiving the error any longer. Instead, you must attempt as follows.

var jwt = require("jsonwebtoken");

const validateToken = (res, req, next) => {
const accesToken = req.header("accesToken");
const stringAccesToken = accesToken;

if (!stringAccesToken) {
   return res.json({ error: "user not logged in" });
}

jwt.verify(stringAccesToken, "importantSecret", function (err, decoded) {
  if (err)
    return console.log(err)
  // Next Code
  next();
 });
};

module.exports = { validateToken };
妄司 2025-02-20 11:28:37

我找到了解决方案:
正如错误所说的JWT需要是字符串的那样,

我首先尝试使用Accestoken.tostring()给出[对象对象],
第二次尝试,我使用了json.stringy,这也没有成功。

最终的scuccesful Attemp是使用库名称-Talpated(将JSON转换为String,并且使用后,我才使用Split Split,直到我没有获得令牌)。

faltted(link) - https://github.com/webreflection/webreflection/flatted#flatted

>工作解决方案 -

authmiddleware.js

const { parse, stringify, toJSON, fromJSON } = require('flatted');



const validateToken = (res, req, next) => {


    const authToken = req.header("accessToken");
    const string = stringify(authToken)
    const token = string && string.split(' ')[2];
    const tokenPure = token.split('"')[4]

    if (!tokenPure) {
        return res.json({ error: "user not logged in" })

    }
    try {
        const validToken = verify(tokenPure, "importantSecret");
        // console.log(validToken, 'validtoken')
        if (validToken) {
            return next();
        }
    } catch (err) {
        console.log(err, "error")
    }

}

module.exports = { validateToken }

I found the solution:
As the error said JWT need to be string,

I first tried using accesToken.toString() that gives [object object],
On second try i used JSON.stringy and that was also unsuccessful.

Final scuccesful attemp was to use library name - flatted (to convert json to string and after using it i just used split till i did'nt get the token).

faltted (link) - https://github.com/WebReflection/flatted#flatted

Worked Solution -

AuthMiddleware.js

const { parse, stringify, toJSON, fromJSON } = require('flatted');



const validateToken = (res, req, next) => {


    const authToken = req.header("accessToken");
    const string = stringify(authToken)
    const token = string && string.split(' ')[2];
    const tokenPure = token.split('"')[4]

    if (!tokenPure) {
        return res.json({ error: "user not logged in" })

    }
    try {
        const validToken = verify(tokenPure, "importantSecret");
        // console.log(validToken, 'validtoken')
        if (validToken) {
            return next();
        }
    } catch (err) {
        console.log(err, "error")
    }

}

module.exports = { validateToken }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文