簡體   English   中英

如何使用 React 和 Node JS 實現 http-only cookie-JWT 身份驗證?

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

我是編程新手,剛開始使用 NodeJS 和 React 進行全棧項目。 我不久前在某處讀到,在安全性方面,將 JWT 令牌保存在 http-only cookies 中比僅將它們保存在本地存儲中更好,所以我決定實現它,但不知道如何實現。

這是我在 express 的登錄 controller

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" });
};

但我不知道如何使用 React 訪問存儲的 cookie,然后對用戶進行身份驗證。

這是我在 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;

如果在檢查或 POSTMAN 中檢查,則令牌確實存儲在 cookie 中: postman 屏幕截圖

當我使用 EJS forms 時,我個人實現了驗證用戶是否經過身份驗證並且它有效:

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");
  }
};

我需要實現類似的東西嗎?

您無法在瀏覽器中訪問 httpOnly cookie,它只是發送到瀏覽器,因此可以在后端使用。 您可以在后端應用程序中訪問它。 我的意思是,如果在瀏覽器中訪問 httpOnly cookie,它類似於 localStorage。 學習實現用於驗證和授權的 accessToken 和 refreshToken 方法。

這是一個例子:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM