I'm trying to create Protected Routes for my React project, on Back-End I have NodeJS. I look at quite a few examples and they use localStorage or "fakeAuth" so I don't really get proper info I need, the main problem I encountered is that when I log in how should I save that information that I'm logged in ATM so my Front-End part could see that.
In my PrivateRoute component I need to have boolean that describes my stats(Logged In or not), but I don't really get it how should I "extract" that information from my Back-End my PrivateRoute component: (Boolean should be in place of {{??????????????}} )
import React from "react";
import { Route, Redirect } from "react-router-dom";
import {authentication} from "./login.component"
import axios from 'axios';
export const PrivateRoute = ({ component: Component, ...rest}) => (
<Route
{...rest}
render={props =>
{{??????????????}} ? (
<Component {...props} />
) : (
<Redirect
to={{
pathname: "/login",
state: { from: props.location }
}}
/>
)
}
/>
);
Here is my Log in component:
import React, { useState } from 'react';
import axios from 'axios';
const Login = () => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const onChangeUsername = (e) => {
setUsername(e.target.value);
};
const onChangePassword= (e) => {
setPassword(e.target.value);
};
const onSubmit = async (e) => {
const user = {
username: username,
password: password
};
e.preventDefault();
await axios.post('http://localhost:5000/users/login', user);
};
return (
<div className="Login">
<h2>Traffic scan admin panel</h2>
<div className="LoginInfo-Logins">
<form>
<input type="text"
required
className=""
value={username}
onChange={onChangeUsername}
placeholder="Username*"
/>
<input type="text"
required
className=""
value={password}
onChange={onChangePassword}
placeholder="Password*"
/>
</form>
</div>
<button onClick={onSubmit}>SIGN IN</button>
</div>
)
}
export default Login;
And here is my Back-End part:
require('dotenv').config();
const router = require('express').Router();
const Users = require('../models/user.model');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');
router.route('/').get(authenticateToken, async (req, res) => {
const user = await Users.findOne({username: req.body.username});
if(!user) throw Error('User do not exist')
res.json(user)
});
router.route('/add').post(async (req, res) => {
try {
const hashedPassword = await bcrypt.hash(req.body.password, 10); // 10 is const salt = await bcrypt.genSalt/*10 is default*/);
const email = req.body.email;
const username = req.body.username;
const password = hashedPassword;
const IP = req.connection.remoteAddress;
const newUser = new Users({
email,
username,
password,
IP
});
newUser.save()
.then(() => res.json('User added!'))
.catch(err => res.status(400).json('Error: ' + err));
} catch {
res.status(500).send()
}
});
router.route('/login').post(async (req, res) => {
const user = await Users.findOne({username: req.body.username});
if(!user) throw Error('Password or Username')
if(await bcrypt.compare(req.body.password, user.password)) {
const accessToken = jwt.sign(user.toJSON(), process.env.ACCESS_TOKEN_SECRET, {expiresIn: 604800});
res.json({ accessToken: accessToken });
} else throw Error('Password or Username is incorrect');
});
function authenticateToken (req, res, next) {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if(token == null) return res.sendStatus(401);
jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user)=>{
if(err) return res.send(403);
req.user = user;
next();
})
}
module.exports = router;
Maybe someone can help me out, any suggestions, tutorials, examples on how to do it would help.