skip to Main Content

I am still a beginner in ReactJS and MERN stack as a whole. The Activate.js code below basically means when the useEffect() hook runs, we will have the jwt token that was taken from the route parameter/url using the {match} props. We decode the token to get the name. Finally, the name and token will be used to save it back in the state – useState({})

Activate.js

import React, { useState, useEffect } from 'react';
import { Link, Redirect, useParams } from 'react-router-dom';
import Layout from '../core/Layout';
import axios from 'axios';
import jwt from 'jsonwebtoken';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.min.css';

const Activate = ({match}) => {
  const [values, setValues] = useState({
    name: '',
    token: '',
    show: true
  }); // values is an object while setValues is a function

  let paramsToken = useParams(); // useParams replaced match.params.id on react-router-dom 6

  useEffect(() => {
    // let token = match.params.token; // obsolete
    let token = paramsToken;
    let { name } = jwt.decode(token); // destructure to get the name,

    if (token) {
      setValues({...values, name, token});
    }

  }, []);

  const { name, token, show } = values; // destructure

  const clickSubmit = event => {
    // code snippet
  };

  const activationLink = () => (
    <div>
      <h1 className="p-5 text-center">Hey {name}, Ready to activate your account?</h1>
      <button className="btn btn-outline-primary" onClick={clickSubmit}>Activate Account</button>
    </div>
  ); // used parenthesis so we don't use the return keyword

  return (
    <Layout>
      <div className="col-md-6 offset-md-3">
        <ToastContainer />
        {/* {JSON.stringify({name, email, password})}*/} {/* We can use this to know the value in the state */}
        {activationLink()}
      </div>
    </Layout>
  );
};

export default Activate;

package.json

{
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "axios": "^1.3.6",
    "jsonwebtoken": "^9.0.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.10.0",
    "react-scripts": "5.0.1",
    "react-toastify": "^9.1.2",
    "web-vitals": "^2.1.4"
  }
}

Problem: The problem I am currently facing with jsonwebtoken package is that I am prompted with 2-3 errors and I have indicated those errors below. Please take note that I am following a tutorial and the tutorial’s code is for 3 years ago and my latest node.js version and other packages are installed as of March 2023.

Module not found: Error: Can’t resolve ‘buffer’ in
‘C:UsersjohnDocumentsnode-projectsreactmern-ultimate-authenticationmern-auth-clientnode_modulesbuffer-equal-constant-time’

Module not found: Error: Can’t resolve ‘crypto’ in
‘C:UsersjohnDocumentsnode-projectsreactmern-ultimate-authenticationmern-auth-clientnode_modulesjsonwebtoken’

Module not found: Error: Can’t resolve ‘crypto’ in
‘C:UsersjohnDocumentsnode-projectsreactmern-ultimate-authenticationmern-auth-clientnode_modulesjsonwebtoken’

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js
core modules by default….

Do you know how to solve the issue above? Any help is greatly appreciated. Thanks

2

Answers


  1. Chosen as BEST ANSWER

    I was able to solve the issue by using the jwt-decode package as recommended by another stackoverflow user.

    For those who are looking for the correct answer, I have included the updated code below.

    Activate.js

    import React, { useState, useEffect } from 'react';
    import { Link, Redirect, useParams } from 'react-router-dom';
    import Layout from '../core/Layout';
    import axios from 'axios';
    import jwt_decode from "jwt-decode";
    import { ToastContainer, toast } from 'react-toastify';
    import 'react-toastify/dist/ReactToastify.min.css';
    
    const Activate = ({match}) => {
      const [values, setValues] = useState({
        name: '',
        token: '',
        show: true
      }); // values is an object while setValues is a function
    
      let paramsToken = useParams(); // useParams replaced match.params.id on react-router-dom 6
    
      useEffect(() => {
        // let token = match.params.token; // obsolete
        let token = paramsToken;
        // we don't need to type token.name if we destructure it
        let { name } = jwt_decode(JSON.stringify(token)); // jwt_decode() requires the token to be converted into string first
    
        if (token) {
          setValues({...values, name, token});
        }
      }, []);
    
      const { name, token, show } = values; // destructure
    
      const clickSubmit = event => {
        // code snippet
      };
    
      const activationLink = () => (
        <div>
          <h1 className="p-5 text-center">Hey {name}, Ready to activate your account?</h1>
          <button className="btn btn-outline-primary" onClick={clickSubmit}>Activate Account</button>
        </div>
      ); // used parenthesis so we don't use the return keyword
    
      return (
        <Layout>
          <div className="col-md-6 offset-md-3">
            <ToastContainer />
            {/* {JSON.stringify({name, email, password})}*/} {/* We can use this to know the value in the state */}
            {activationLink()}
          </div>
        </Layout>
      );
    };
    
    export default Activate;
    

  2. if you want to use jwt.decode() i think you should import the package :

    import * as jwt_decode from 'jwt-decode';
    

    or if you want to use jwt.verify()
    like this :

    jwt.verify(yourToken,yourJWTKey,callbackfunction(error,userData){
      // your code here
    })
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search