0

I write a code for a sample project of an ecommerce web application. Everything is working fine like login, registration, admin dashboard. Reading from api is perfectly working. Every protected admin route is working absolutely fine with POSTMAN. But whenever I try to create, update or delete a product from the frontend it throws a error as below. Please help me solve

JsonWebTokenError: jwt must be provided [0] at module.exports [as verify] (C:\Users\Bangladesh One\Desktop\ReactJs\eCommerceApp\node_modules\jsonwebtoken\verify.js:60:17) [0] at requireSignIn (file:///C:/Users/Bangladesh%20One/Desktop/ReactJs/eCommerceApp/middlewares/authMiddleware.js:8:24) [0] at Layer.handle [as handle_request] (C:\Users\Bangladesh One\Desktop\ReactJs\eCommerceApp\node_modules\express\lib\router\layer.js:95:5) [0] at next (C:\Users\Bangladesh One\Desktop\ReactJs\eCommerceApp\node_modules\express\lib\router\route.js:144:13) [0] at Route.dispatch (C:\Users\Bangladesh One\Desktop\ReactJs\eCommerceApp\node_modules\express\lib\router\route.js:114:3) [0] at Layer.handle [as handle_request] (C:\Users\Bangladesh One\Desktop\ReactJs\eCommerceApp\node_modules\express\lib\router\layer.js:95:5) [0] at C:\Users\Bangladesh One\Desktop\ReactJs\eCommerceApp\node_modules\express\lib\router\index.js:284:15 [0] at Function.process_params (C:\Users\Bangladesh One\Desktop\ReactJs\eCommerceApp\node_modules\express\lib\router\index.js:346:12) [0] at next (C:\Users\Bangladesh One\Desktop\ReactJs\eCommerceApp\node_modules\express\lib\router\index.js:280:10) [0] at Function.handle (C:\Users\Bangladesh One\Desktop\ReactJs\eCommerceApp\node_modules\express\lib\router\index.js:175:3)

I tried with POSTMAN if my admin routes are working fine and I got positive result with POSTMAN. But whenever I try to create, update, delete a product with frontend it throws error. But login , register is working fine

Here is my middleware

import JWT from "jsonwebtoken";
import userModel from "../models/userModel.js";
import asyncHandler from "express-async-handler"

//Protected Routes token base
export const requireSignIn = async (req, res, next) => {
  try {
    const decode = JWT.verify(
      req.headers.authorization,
      process.env.JWT_SECRET
    );
    req.user = decode;
    next();
  } catch (error) {
    console.log(error);
  }
};

//admin acceess
export const isAdmin = async (req, res, next) => {
  try {
    const user = await userModel.findById(req.user._id);
    if (user.role !== 1) {
      return res.status(401).send({
        success: false,
        message: "UnAuthorized Access",
      });
    } else {
      next();
    }
  } catch (error) {
    console.log(error);
    res.status(401).send({
      success: false,
      error,
      message: "Error in admin middelware",
    });
  }
};

My Create Category Frontend code is here

import React, { useEffect, useState } from "react";
import Layout from "../../component/Layout/Layout";
import AdminMenu from "../../component/Layout/AdminMenu";
import axios from "axios";
import CategoryForm from "../../component/Form/CategoryForm";
import { Modal } from "antd";
const CreateCategory = () => {
  const [categories, setCategories] = useState([]);
  const [name, setName] = useState("");
  const [visible, setVisible] = useState(false);
  const [selected, setSelected] = useState(null);
  const [updatedName, setUpdatedName] = useState("");
  //handle Form
  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      const { data } = await axios.post(
        "http://localhost:8080/api/v1/category/create-category",
        {
          name
        }
      );
      if (data?.success) {
        alert(`${name} is created`);
        getAllCategory();
      } else {
        alert(data.message);
      }
    } catch (error) {
      console.log(error);
      alert(data.message);
    }
  };

  //get all cat
  const getAllCategory = async () => {
    try {
      const { data } = await axios.get(
        "http://localhost:8080/api/v1/category/get-category"
      );
      if (data.success) {
        setCategories(data.category);
      }
    } catch (error) {
      console.log(error);
      alert("Something wwent wrong in getting catgeory");
    }
  };

  useEffect(() => {
    getAllCategory();
  }, []);

  //update category
  const handleUpdate = async (e) => {
    e.preventDefault();
    try {
      const { data } = await axios.put(
        `http://localhost:8080/api/v1/category/update-category/${selected._id}`,
        { name: updatedName }
      );
      if (data.success) {
        alert(`${updatedName} is updated`);
        setSelected(null);
        setUpdatedName("");
        setVisible(false);
        getAllCategory();
      } else {
        alert(data.message);
      }
    } catch (error) {
      alert(data.message);
    }
  };
  //delete category
  const handleDelete = async (pId) => {
    try {
      const { data } = await axios.delete(
        `http://localhost:8080/api/v1/category/delete-category/${pId}`
      );
      if (data.success) {
        alert(`category is deleted`);

        getAllCategory();
      } else {
        alert(data.message);
      }
    } catch (error) {
      alert(data.message);
    }
  };
  return (
    <Layout title={"Dashboard - Create Category"}>
      <div className="container-fluid m-3 p-3">
        <div className="row">
          <div className="col-md-3">
            <AdminMenu />
          </div>
          <div className="col-md-9">
            <h1>Manage Category</h1>
            <div className="p-3 w-50">
              <CategoryForm
                handleSubmit={handleSubmit}
                value={name}
                setValue={setName}
              />
            </div>
            <div className="w-75">
              <table className="table">
                <thead>
                  <tr>
                    <th scope="col">Name</th>
                    <th scope="col">Actions</th>
                  </tr>
                </thead>
                <tbody>
                  {categories?.map((c) => (
                    <>
                      <tr>
                        <td key={c._id}>{c.name}</td>
                        <td>
                          <button
                            className="btn btn-primary ms-2"
                            onClick={() => {
                              setVisible(true);
                              setUpdatedName(c.name);
                              setSelected(c);
                            }}
                          >
                            Edit
                          </button>
                          <button
                            className="btn btn-danger ms-2"
                            onClick={() => {
                              handleDelete(c._id);
                            }}
                          >
                            Delete
                          </button>
                        </td>
                      </tr>
                    </>
                  ))}
                </tbody>
              </table>
            </div>
            <Modal
              onCancel={() => setVisible(false)}
              footer={null}
              open={visible}
            >
              <CategoryForm
                value={updatedName}
                setValue={setUpdatedName}
                handleSubmit={handleUpdate}
              />
            </Modal>
          </div>
        </div>
      </div>
    </Layout>
  );
};

export default CreateCategory;
protob
  • 3,317
  • 1
  • 8
  • 19
  • 2
    Looks like the token is not set in `req.headers.authorization`. Include your frontend code to analyze further – Shri Hari L Apr 10 '23 at 06:00
  • Frontend code added. Please Analyze and help – Azizul Hakim Apr 10 '23 at 06:37
  • You need to set the `authorization` header when you are sending the request. Basically, you need to do something like `authorization` header = JWT. This might help https://stackoverflow.com/a/45581882/10217754 – Parth Kapadia Apr 10 '23 at 06:41
  • I tried adding headers but it is showing x Expected ',', got ':' ,-[C:/Users/Bangladesh One/Desktop/ReactJs/eCommerceApp/client/src/pages/Admin/CreateCategory.jsx:19:1] 19 | { 20 | name, 21 | }, 22 | headers:{ : ^ 23 | Athorization: token 24 | } 24 | ); – Azizul Hakim Apr 10 '23 at 07:10
  • Store the JWT token in LocalStorage and use Axios Interceptor. Follow: https://stackoverflow.com/questions/73283693/how-to-pass-token-to-local-storage-with-axios – Shri Hari L Apr 10 '23 at 07:19
  • JWT token already in LocalStorage still getting same error – Azizul Hakim Apr 10 '23 at 07:49
  • Did you setup the interceptors? – Shri Hari L Apr 10 '23 at 09:03

1 Answers1

1

Looks like you are not sending the JWT from your frontend code to your backend. You need to set the authorization header in each of your axios requests (at least in each request where you are executing the requireSignIn middleware).

To add a header in your axios refer this. One way to do it is adding the header in each of your axios request -

Do ensure that you are storing the jwt in your local storage - Refer - How to get/set items in localstorage and How to view localstorage items in browser

// Replace jwt with the variable name that you used to set the token
const token = localStorage.getItem("jwt");
axios.get('sampleURL', {
 headers: {
   Authorization: token
 }
})

// for post/put etc
axios.post('sampleURL', {
 name: updatedName 
},
{
  headers: {
    Authorization: token
  }
})

Another, and easy, way of doing this is using a Axios interceptor. This will add a header to all the requests before sending them to your backend server and hence will save you the effort of inserting headers everytime you send a request manually.

Inside your app.js-

axios.interceptors.request.use(function (config) {
    // Intercept the request and set the token before sending it to backend
    const token = localStorage.getItem("jwt"); 
    config.headers.Authorization =  token;
    return config;
  }, function (error) {
    // Do something with request error
    return Promise.reject(error);
  });

The error that you mentioned in the comments looks like a syntax issue with brackets and commas. Make sure you aren't missing any commas before the headers/data in the axios request and that the syntax is correct.

Parth Kapadia
  • 507
  • 6
  • 18