Не Удалось Проверить Ошибку Типа Токена, Реагирующее Приложение

#reactjs #mongodb #authentication #jwt

Вопрос:

Я создаю приложение React с аутентификацией с использованием JWTs. Я могу создать нового пользователя. Я могу войти в систему этого пользователя. Но я не могу обновить информацию об этом пользователе в MongoDB, к которому он подключен. Ошибка, которую я получаю, заключается в следующем:

 '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 = () =gt; {  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(() =gt; {  if (showSuccessMessage || showErrorMessage) {  setTimeout(() =gt; {  setShowSuccessMessage(false);  setShowErrorMessage(false);  }, 3000);  }  }, [showSuccessMessage, showErrorMessage]);   const saveChanges = async () =gt; {  // 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 = () =gt; {  // 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 = () =gt; {  // 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 (  lt;div className="content-container"gt;  lt;h1gt;Info for {email}lt;/h1gt;  {showSuccessMessage amp;amp; lt;div className="success"gt;Successfully saved user data!lt;/divgt;}  {showErrorMessage amp;amp; lt;div className="fail"gt;Uh oh... something went wrong and we couldn't save changeslt;/divgt;}  lt;labelgt;  Favorite Food:  lt;input  onChange={e =gt; setFavoriteFood(e.target.value)}  value={favoriteFood} /gt;  lt;/labelgt;  lt;labelgt;  Hair Color:  lt;input  onChange={e =gt; setHairColor(e.target.value)}  value={hairColor} /gt;  lt;/labelgt;  lt;labelgt;  Bio:  lt;input  onChange={e =gt; setBio(e.target.value)}  value={bio} /gt;  lt;/labelgt;  lt;hr /gt;  lt;button onClick={saveChanges}gt;Save Changeslt;/buttongt;  lt;button onClick={resetValues}gt;Reset Valueslt;/buttongt;  lt;button onClick={logOut}gt;Log Outlt;/buttongt;  lt;/divgt;  ); }  

Внутренний маршрут, по которому отправляется запрос:

updateUserInfoRoute.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) =gt; {   try{  const{ authorization } = req.headers;  const {userId} = req.params;   const updates = (  ({  favoriteFood,  hairColor,  bio,  }) =gt; ({  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 ) =gt; {  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) =gt;{  if(err){  return res.status(200).json(err);  }  res.status(200).json({ token });  })  })  }catch(error){  console.log("Mazzo the error is: "   error);  }    }, }  

В чем здесь проблема? Спасибо тебе, Железный человек

Ответ №1:

Вы передаете токен с интерфейса на сервер в этом формате,

 Bearer token  

Но на маршруте обновления.код js, вы разделяете токен без пробела,

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

Для этого кода вывод токена будет

 e  

Чтобы решить эту проблему, просто добавьте место в методе разделения,

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

Комментарии:

1. Вы попали в точку. Большое спасибо, парень. Я отмечу ваш ответ как решение. Выпей хорошего.