三行代码  ›  专栏  ›  技术社区  ›  Ironman

无法验证令牌类型错误反应应用程序

  •  0
  • Ironman  · 技术社区  · 4 天前

    'Unable to verify token'
    

    UserInfoPage.js

    import { useState, useEffect } from 'react';
    import { useHistory } from 'react-router-dom';
    import axios from 'axios';
    import { useToken } from '../auth/useToken';
    import { useUser } from '../auth/useUser';
    
    export const UserInfoPage = () => {
        const user = useUser();
        const [token,setToken] = useToken();
    
        const {id, email, info } = user;
    
        // We'll use the history to navigate the user
        // programmatically later on (we're not using it yet)
        const history = useHistory();
    
        // These states are bound to the values of the text inputs
        // on the page (see JSX below). 
        const [favoriteFood, setFavoriteFood] = useState(info.favoriteFood || '');
        const [hairColor, setHairColor] = useState(info.hairColor || '');
        const [bio, setBio] = useState(info.bio || '');
    
        // These state variables control whether or not we show
        // the success and error message sections after making
        // a network request (see JSX below).
        const [showSuccessMessage, setShowSuccessMessage] = useState(false);
        const [showErrorMessage, setShowErrorMessage] = useState(false);
    
        // This useEffect hook automatically hides the
        // success and error messages after 3 seconds when they're shown.
        // Just a little user interface improvement.
        useEffect(() => {
            if (showSuccessMessage || showErrorMessage) {
                setTimeout(() => {
                    setShowSuccessMessage(false);
                    setShowErrorMessage(false);
                }, 3000);
            }
        }, [showSuccessMessage, showErrorMessage]);
    
        const saveChanges = async () => {
            // Send a request to the server to
            // update the user's info with any changes we've
            // made to the text input values
            //alert('Save functionality not implemented yet');
            try{
                const response = await axios.put(`/api/users/${id}`, {
                    favoriteFood,
                    hairColor,
                    bio,
                }, {
                    headers: { Authorization: `Bearer ${token}`}
                });
    
                const { token: newToken } = response.data;
                setToken(newToken);
                setShowSuccessMessage(true);
    
            }catch(error){
                setShowErrorMessage(true);
                console.log(error);
            }
        }
    
        const logOut = () => {
            // We'll want to log the user out here
            // and send them to the "login page"
            alert('Log out functionality not implemented yet');
        }
        
        const resetValues = () => {
            // Reset the text input values to
            // their starting values (the data we loaded from the server)
            //alert('Reset functionality not implemented yet');
            
                setFavoriteFood(info.favoriteFood);
                setHairColor(info.hairColor);
                setBio(info.bio);
            
        }
        
        // And here we have the JSX for our component. It's pretty straightforward
        return (
            <div className="content-container">
                <h1>Info for {email}</h1>
                {showSuccessMessage && <div className="success">Successfully saved user data!</div>}
                {showErrorMessage && <div className="fail">Uh oh... something went wrong and we couldn't save changes</div>}
                <label>
                    Favorite Food:
                    <input
                        onChange={e => setFavoriteFood(e.target.value)}
                        value={favoriteFood} />
                </label>
                <label>
                    Hair Color:
                    <input
                        onChange={e => setHairColor(e.target.value)}
                        value={hairColor} />
                </label>
                <label>
                    Bio:
                    <input
                        onChange={e => setBio(e.target.value)}
                        value={bio} />
                </label>
                <hr />
                <button onClick={saveChanges}>Save Changes</button>
                <button onClick={resetValues}>Reset Values</button>
                <button onClick={logOut}>Log Out</button>
            </div>
        );
    }
    

    UpdateUserInfo.js

    import jwt from 'jsonwebtoken';
    import { ObjectID } from 'mongodb';
    import { getDbConnection } from '../db';
    
    export const updateUserInfoRoute = { 
    
        path: '/api/users/:userId',
        method: 'put',
        handler: async (req, res) => {
    
        try{
            const{ authorization } = req.headers;
            const {userId} = req.params;
    
            const updates = (
                ({
                favoriteFood,
                hairColor,
                bio,
                }) => ({
                favoriteFood,
                hairColor,
                bio,
            }))(req.body);
    
            if (!authorization){
                return res.status(401).json({message: 'No authorization headers sent'});
            }
    
            const token = authorization.split('')[1];
    
            jwt.verify(token, process.env.JWT_SECRET, async (err, decoded ) => {
                if (err) return res.status(401).json({message: 'Unable to verify token'});
                console.log(err);
    
                const { id } = decoded;
    
                if (id !== userId) return res.status(403).json({message: 'No authorization to update user data' });
    
                const db = getDbConnection('react-auth-db');
                const result = await db.collection('users').findOneAndUpdate(
                    { _id: ObjectID(id) },
                    { $set: { info: updates }},
                    { returnOriginal: false},
                );
                const {email, isVerified, info } = result.value;
    
                jwt.sign({ id, email, isVerified, info }, process.env.JWT_SECRET, {expiresIn: '365d'}, (err, token) =>{
                    if(err){
                        return res.status(200).json(err);
                    }
                    res.status(200).json({ token });
                })
            })
        }catch(error){
            console.log("Mazzo the error is: " + error);
        }
            
        },
    }
    

    这里的问题是什么?非常感谢。

    1 回复  |  直到 4 天前
        1
  •  0
  •   tareqmahmud    4 天前

    您使用此格式将令牌从前端传递到后端,

    Bearer token
    

    const token = authorization.split('')[1];
    

    对于此代码,令牌输出将是

    e
    

    要解决这个问题,只需在split方法上添加空间,

    const token = authorization.split(' ')[1];