I am new to programming and just started full-stack project with NodeJS and React. I read somewhere a while ago that saving JWT tokens inside http-only cookies is better in terms of security than just saving them in localstorage, so I decided to implement that, but don't know how.
This is my Login controller in express
const signIn = async (req: Request, res: Response): Promise<any> => {
const userEmail = req.body.email;
const userPassword = req.body.password;
const user: any = await User.findOne({ email: userEmail }).clone();
const isValid = await user.comparePassword(userPassword);
if (isValid) {
const tokenObject = utils.issueJWT(user);
res.cookie("jwt", tokenObject.token, {
httpOnly: true,
maxAge: tokenObject.expiresIn,
});
res.send(tokenObject.token);
} else
res
.status(401)
.json({ success: false, msg: "You entered the wrong password" });
};
But I don't know how to access stored cookie with React and then authenticate user.
This is my Login component in React
import { SyntheticEvent, useState } from "react";
import { Navigate } from "react-router-dom";
import "bootstrap/dist/css/bootstrap.min.css";
function SignIn() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [navigate, setNavigate] = useState(false);
const submit = async (e: SyntheticEvent) => {
e.preventDefault();
await fetch("http://localhost:8080/login", {
method: "POST",
headers: { "Content-type": "application/json" },
body: JSON.stringify({ email, password }),
credentials: "include",
});
setNavigate(true);
};
if(navigate){
return <Navigate to="/users"/>
}
return (
<form action="/login" method="post" onSubmit={submit}>
<div className="form-outline mb-4">
<input
type="email"
id="form2Example1"
className="form-control"
name="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<label className="form-label" htmlFor="form2Example1">
Email address
</label>
</div>
<div className="form-outline mb-4">
<input
type="password"
id="form2Example2"
className="form-control"
name="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<label className="form-label" htmlFor="form2Example2">
Password
</label>
</div>
<button type="submit" className="btn btn-primary btn-block mb-4">
Sign in
</button>
</form>
);
}
export default SignIn;
Token is really stored inside cookie if checked in inspect or POSTMAN: postman screenshot
While I worked with EJS forms I had my personal implementation of verifying if the user was authenticated or not and it worked:
const verifyJWT = (req: Request, res: Response, next: NextFunction) => {
const signedToken = req.cookies.jwt;
if (signedToken) {
jwt.verify(
signedToken,
config.PRIV_KEY,
{ algorithms: ["RS256"] },
async (err: any, decodedToken: any) => {
if (err) {
// tslint:disable-next-line:no-console
console.log(err);
} else {
// tslint:disable-next-line:no-console
console.log(decodedToken);
next();
}
}
);
} else {
res.redirect("/login");
}
};
Do I need to implement something similar to this?
You cannot access httpOnly cookie in browser it is just send along to browser so it can then be used in the backend. You can access it in your backend app. I mean if httpOnly cookie is accessed in browser than it is similar to localStorage. Learn to implement the accessToken and refreshToken approach for Auethntication and authorization.
This is one example:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.