Pv33_
Pv33_

Reputation: 25

How to get the current user information using JWT in MERN

I am working on displaying the current user's information, such as their username and email, on the account page of my application. I am using JWT for authentication, but I am consistently encountering issues. How to properly implement this functionality?

user.model.js:

import mongoose from 'mongoose';


const UserSchema = new mongoose.Schema({
    username: {
        type: String,
        required: [true, 'Username is required'],
        unique: true,
    },
    email: {
        type: String,
        required: [true, 'Email is required'],
        unique: true,
    },
    password : {
     type: String,
     required: [true, 'Password is required'],
    },
    role : {
     type: String,
     enum: ['Admin','User'],
     default: 'User'
    }
    
})


const User = mongoose.model('User', UserSchema);

export default User;   

user.controller.js:

import User from "../models/user.model.js";
import bcrypt from "bcrypt";
import jwt from "jsonwebtoken"; 
import dotenv from "dotenv";

dotenv.config();

const SECRET_KEY = process.env.SECRET_KEY;


export const createUser = async (req, res) => {
    try {
        const { username, email,password} = req.body;
        const hashedPassword = await bcrypt.hash(password, 10);
        const newUser = new User({ username,email, password: hashedPassword });
        await newUser.save();
        res.status(201).json({ success: true , message: 'User created successfully' });
    }
    catch(err){
        res.status(500).json({ success: false, message: err.message });

    }
}

export const getUsers = async (req, res) => {
    try  {
        const users = await User.find();
        res.status(200).json({ success: true, data: users });
    }
    catch(err){
        res.status(500).json({ success: false, message: err.message });
    }
}


export const loginUser = async (req, res) => {
    try{
        const {username,password} = req.body;
        const user = await User.findOne({username});
        if(!user){
            return res.status(404).json({ success: false, message: 'Username or password is incorrect' });
        }
        const isPasswordValid = await bcrypt.compare(password, user.password);
        if(!isPasswordValid){
            return res.status(401).json({ success: false, message: 'Username or password is incorrect' });
        }
        const token = jwt.sign({ userId: user._id}, SECRET_KEY, { expiresIn: '1h' })
        res.status(200).json({ success: true, message: 'Login successful' } );
        
    }
    catch(err){
        res.status(500).json({ success: false, message: err.message });
    }
}

export const getUserInfo = async (req, res) => {
    try {
        const user = await User.findById(req.params.id).select('-password'); // Exclude the password
        if (!user) {
            return res.status(404).json({ message: 'User not found' });
        }
        res.status(200).json(user);
    } catch (error) {
        res.status(500).json({ message: error.message });
    }
}

SignUp.jsx:

import React,{useState} from 'react';
import { Box, Center, Input, Button ,Divider  } from '@chakra-ui/react';
import { useNavigate } from 'react-router-dom';
import axios from 'axios';


const SignUp = () => {
  
  const [username,setUsername] = useState("");
  const [email,setEmail] = useState("");
  const [password,setPassword] = useState("");
  const navigate = useNavigate();
  
  const handleRegister = async (event) => {
    event.preventDefault();
    axios.post('http://localhost:5000/api/auth/register',{username,email,password})
    .then(()=>{
      setUsername("");
      setEmail("");
      setPassword("");
      alert("User registered successfully");
      navigate("/login");
    }).catch((err) =>{
      console.log(err);
    }) 
  } 

  return (
    <Box
      display="flex"
      alignItems="center"
      justifyContent="center"
      minHeight="100vh"
    >
      <Box 
        w="400px" 
        p="6" 
        boxShadow="lg" 
        borderRadius="md" 
        background="white"
      >
        <Center>
          <h1 style={{fontSize:"25px" , fontWeight: "bold", fontFamily: "sans-serif"}}>Sign Up</h1>
        </Center>
        <br />
        <Divider />
        <br />
        <form onSubmit={handleRegister}>
          <label htmlFor="username">Username</label>
          <Input 
            id="username" 
            type="text" 
            placeholder="Enter your username" 
            mt="2" 
            mb="4" 
            value={username}
            onChange ={(e) => setUsername(e.target.value)} 
          />
          <label htmlFor="email">Email</label>
          <Input 
            id="email" 
            type="email" 
            placeholder="Enter your email" 
            mt="2" 
            mb="4" 
            value={email}
            onChange ={(e) => setEmail(e.target.value)}
          />
          <label htmlFor="password">Password</label>
          <Input 
            id="password" 
            type="password" 
            placeholder="Enter your password" 
            mt="2" 
            mb="4" 
            value={password}
            onChange ={(e) => setPassword(e.target.value)}
          />
          <Button type="submit" backgroundColor={'#CBD5E0'} width="full" mt="4" >Sign Up</Button>
        </form>
      </Box>
    </Box>
  );
}

export default SignUp;

Login.jsx:

import React,{useState , useEffect} from 'react';
import { Box, Center, Input, Button ,Divider  } from '@chakra-ui/react';
import { useNavigate } from 'react-router-dom';
import axios from 'axios';

const Login = () => {
  const [user , setUsers] = useState([])
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const navigate = useNavigate();

  const handleLogin = async (event)=>{
    event.preventDefault();
    try{
      const response = await axios.post('http://localhost:5000/api/auth/login',{username,password});
      const token = response.data.token;
      console.log(token);
      setUsername("");
      setPassword("");
      // navigate('/');
      // window.location.reload();
      localStorage.setItem('token',token);
    } catch(err){}
  }

  return (
    <Box
      display="flex"
      alignItems="center"
      justifyContent="center"
      minHeight="100vh"
    >
      <Box 
        w="400px" 
        p="6" 
        boxShadow="lg" 
        borderRadius="md" 
        background="white"
      >
        <Center>
          <h1 style={{fontSize:"25px" , fontWeight: "bold", fontFamily: "sans-serif"}} >Login</h1>
        </Center>
        <br />
        <Divider />
        <br />
        <form onSubmit={handleLogin}>
          <label htmlFor="email">Username</label>
          <Input 
            id="username" 
            type="username" 
            placeholder="Enter your username" 
            mt="2" 
            mb="4"
            value={username}
            onChange ={(e) => setUsername(e.target.value)} 
          />
          <label htmlFor="password">Password</label>
          <Input 
            id="password" 
            type="password" 
            placeholder="Enter your password" 
            mt="2" 
            mb="4" 
            value={password}
            onChange ={(e) => setPassword(e.target.value)}
          />
          <Button type="submit" backgroundColor={'#CBD5E0'}  width="full" mt="4">Login</Button>
        </form>
      </Box>
    </Box>
  );
}

export default Login;

Account.jsx

I am unsure what to include after retrieving the username and email. I have tried various approaches, but the token always appears as undefined. I checked the local storage through the browser's developer tools, and it is also showing as undefined. Could someone please assist me in resolving this issue?

import React from 'react'
import { useState, useEffect } from 'react';
import {Center,Box} from '@chakra-ui/react';
const Account = () => {

  return (
    <Center>
      <Box>
         username : 
         email : 
      </Box>
    </Center>
  )
}

export default Account;

Upvotes: 0

Views: 33

Answers (0)

Related Questions