简体   繁体   English

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

[英]JsonWebTokenError: jwt must be a string, node.js

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.我收到错误JsonWebTokenError: jwt must be a string从前端(react.js)获取 jwt 并在中间件中使用来验证令牌。 If I tried to use toString it gives me another error JsonWebTokenError: jwt malformed .如果我尝试使用 toString 它会给我另一个错误JsonWebTokenError: jwt malformed

Update更新

As soon as i pass the accessToken from frontEnd it converted into object in the AuthMiddleware.js.一旦我从前端传递 accessToken,它就会转换为 AuthMiddleware.js 中的对象。 I'm passing middleware on header in file Post.js(attached below)我在 Post.js 文件的头文件中传递中间件(附在下面)

AuthMiddleware.js 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) User.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;

Post.js 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

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.因为 jwt 令牌使用对象作为输入,而不是使用“验证”一词,所以它不再适用于您收到错误的对象。 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 };

I found the solution: As the error said JWT need to be string,我找到了解决方案:由于错误说 JWT 需要是字符串,

I first tried using accesToken.toString() that gives [object object], On second try i used JSON.stringy and that was also unsuccessful.我第一次尝试使用提供 [object object] 的 accessToken.toString(),第二次尝试我使用 JSON.stringy,但也没有成功。

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).最终成功的尝试是使用库名称 - 扁平化(将 json 转换为字符串,在使用它之后我只是使用 split 直到我没有得到令牌)。

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

Worked Solution -工作解决方案 -

AuthMiddleware.js 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 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM