简体   繁体   中英

How can I implement http-only cookie-JWT authentication using React and Node JS?

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:

https://www.geeksforgeeks.org/jwt-authentication-with-refresh-tokens/#:~:text=Since%20access%20tokens%20aren't,in%20a%20very%20short%20duration .

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM