I did login and registration with node.js. Everything is working, and when I login, I can see a name of the user, but when I refresh the page, the name disappears. What I did wrong, please can you give me some advice?
index.js
const express = require('express');
const app = express();
const cors = require('cors');
const bodyParser = require('body-parser')
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const User = require('./models/User')
const cookieParser = require('cookie-parser')
const mongoose = require('mongoose');
require('dotenv').config();
mongoose.set("strictQuery", false)
const bcryptSalt = bcrypt.genSaltSync(10);
const jwtSecret = 'jkjff8f7sdfsd8sjds9';
app.use(express.json());
app.use(cookieParser());
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
app.use(cors({
credentials:true,
origin: 'http://localhost:5173',
}));
console.log(process.env.MONGO_URL)
mongoose
.connect(process.env.MONGODB_LINK)
.then( () => console.log( 'We were connect to Mongodb'))
.catch( (err) => console.log(err))
app.get('/api/test', (req,res) => {
res.json('test ok')
})
app.post('/api/register', async (req,res) => {
const {name,email,password } = req.body;
try {
const userDoc = await User.create({
name,
email,
password:bcrypt.hashSync(password, bcryptSalt),
})
res.json({userDoc});
} catch (e) {
res.status(422).json(e)
}
});
app.post('/api/login', async (req,res) => {
const {email,password} = req.body;
const userDoc = await User.findOne({email});
if (userDoc) {
const passOk = bcrypt.compareSync(password, userDoc.password);
if (passOk) {
jwt.sign({
email:userDoc.email,
id:userDoc._id
}, jwtSecret, {}, (err,token) => {
if (err) throw err;
res.cookie('token', token).json(userDoc);
});
} else {
res.status(422).json('pass not ok');
}
} else {
res.json('not found');
}
});
app.get('/profile', (req, res) => {
const {token} = req.cookies;
if (token) {
jwt.verify(token, jwtSecret, {}, async (err, userData) => {
if (err) throw err;
const {name,email,_id} = await User.findById(userData.id);
res.json({name,email,_id});
});
} else {
res.json(null)
}
})
app.listen(4000, () => {
console.log('post is listening on 4000')
})
UserContext.jsx
import axios from "axios";
import { createContext, useEffect, useState } from "react";
export const UserContext = createContext({});
export function UserContextProvider({children}) {
const [user, setUser] = useState(null);
const [ready, setReady] = useState(false);
useEffect( () => {
if(!user) {
axios.get('/profile').then(({data}) => {
setUser(data);
setReady(true)
})
}
}, [])
return(
<UserContext.Provider value={{user, setUser,ready}}>
{children}
</UserContext.Provider>
)
}
RegisterPage.jsx
import axios from "axios";
import { useState } from "react";
import { Link } from "react-router-dom"
export default function RegisterPage() {
const [name, setName] = useState('');
const [email,setEmail] = useState('');
const [password, setPassword] = useState('')
async function registerUser(e) {
e.preventDefault();
try {
await axios.post('http://localhost:4000/api/register', {
name,
email,
password,
},
{
withCredentials: true,
credentials: 'include',
});
alert('Registration successful. Now you can log in');
} catch (e) {
alert('Registration failed. Please try again later');
}
}
return (
<div className="mt-4 grow flex items-center justify-around">
<div className="mb-64">
<h1 className="text-4xl text-center mb-4" >Register</h1>
<form className="max-x-md mx-auto " onSubmit={registerUser}>
<input type="text" placeholder="Joy Doe"
value={name}
onChange={ev => setName(ev.target.value)}/>
<input type="email" placeholder="[email protected]"
value={email}
onChange={ev=> setEmail(ev.target.value)}/>
<input type="password" placeholder="password"
value={password}
onChange={ev => setPassword(ev.target.value)}/>
<button className="primary">Register</button>
<div className="text-center py-2 text-gray-500">
Already a member?
<Link className="underline text-black" to={'/login'}> Login</Link>
</div>
</form>
</div>
</div>
)
}
LoginPage.jsx
import { useContext, useState } from "react"
import { Link, Navigate } from "react-router-dom"
import axios from "axios";
import { UserContext } from "../UserContext";
export default function LoginPage() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [redirect, setRedirect] = useState(false);
// http://localhost:4000/login
const {setUser} = useContext(UserContext);
async function handleLoginSubmit(ev) {
ev.preventDefault();
try {
const {data} = await axios.post('http://localhost:4000/api/login',
{
email,
password
},
{
withCredentials: true,
credentials: 'include',
}
);
setUser(data)
alert('Login successful');
setRedirect(true);
} catch (e) {
alert('Login failed')
}
}
if (redirect) {
return <Navigate to={'/'}/>
}
return (
<div className="mt-4 grow flex items-center justify-around">
<div className="mb-64">
<h1 className="text-4xl text-center mb-4" >Login</h1>
<form className="max-x-md mx-auto " onSubmit={handleLoginSubmit}>
<input type="email" placeholder="[email protected]"
value={email}
onChange={ev => setEmail(ev.target.value)}/>
<input type="password" placeholder="password"
value={password}
onChange={ev => setPassword(ev.target.value)}/>
<button className="primary">Login</button>
<div className="text-center py-2 text-gray-500">
Don't have an account yet?
<Link className="underline text-black" to={'/register'}> Register now</Link>
</div>
</form>
</div>
</div>
)
}
Get request localhost:4000 does not work, shows 404 undefined. And when i login I can see user Name, but profile response is null, should be name and email. If i refresh the page i have to login again
I searched answer but could not find anything
Elena is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.