簡體   English   中英

如何在身份驗證中檢查令牌

[英]How to check a token in authentication

我正在嘗試使用 MERN 進行首次身份驗證,但遇到了問題。 我有一個表單,在提交時它會檢查輸入的值,如果沒問題,它應該打開主頁。 我可以在控制台中看到一切正常,我在 cookies 中看到了一個令牌,但我仍然無法打開主頁。 我可以看到問題出在 useToken.js 中,但我完全陷入其中,因為我無法將 localStorage 更改為 cookies。 (該項目非常基礎,我不需要任何驗證,我只需要登錄時查看其他組件)非常感謝您的幫助。 GitHub 存儲庫(如果需要)。 https://github.com/daryalewy/kickstarter-app

Auth.js

import useToken from "../Components/useToken";


export default function Auth() {
  const Body = styled.section`
    min-height: 550px;
    min-width: 319.98px;
    background: linear-gradient(
      0deg,
      rgba(213, 189, 238, 1) 0%,
      rgba(166, 124, 232, 1) 100%
    );
    padding-top: 40px;
    position: relative;
  `;

  const { token, setToken } = useToken();

  if (!token) {
    return (
      <>
        <Body>
          <Logo />
          <Login setToken={setToken} />
        </Body>
        <Socials />
      </>
    );
  }

  return (
    <>
      <BrowserRouter>
        <Switch>
          <Route path="/">
            <MainPage />
          </Route>
        </Switch>
      </BrowserRouter>
    </>
  );
}

useToken.js

import { useState } from 'react';

export default function useToken() {
  const getToken = () => {
    const tokenString = localStorage.getItem('token');
    const userToken = JSON.parse(tokenString);
    return userToken?.token
  };

  const [token, setToken] = useState(getToken());

  const saveToken = userToken => {
    localStorage.setItem('token', JSON.stringify(userToken));
    setToken(userToken.token);
  };

  return {
    setToken: saveToken,
    token
  }
}

后端路由

router.post('/register', async (req, res) => {
  try {
    const { email, password } = req.body;
    if (!isEmail(email)) {
      throw new Error('Email must be a valid email address.');
    }
    if (typeof password !== 'string') {
      throw new Error('Password must be a string.');
    }
    const user = new User({ email, password });
    const persistedUser = await user.save();
    const userId = persistedUser._id;

    const session = await initSession(userId);

    res
      .cookie('token', session.token, {
        httpOnly: true,
        sameSite: true,
        maxAge: 1209600000,
        secure: process.env.NODE_ENV === 'production',
      })
      .status(201)
      .json({
        title: 'User Registration Successful',
        detail: 'Successfully registered new user',
        csrfToken: session.csrfToken,
      });
  } catch (err) {
    res.status(400).json({
      errors: [
        {
          title: 'Registration Error',
          detail: 'Something went wrong during registration process.',
          errorMessage: err.message,
        },
      ],
    });
  }
});

router.post('/login', async (req, res) => {
  try {
    const { email, password } = req.body;
    if (!isEmail(email)) {
      return res.status(400).json({
        errors: [
          {
            title: 'Bad Request',
            detail: 'Email must be a valid email address',
          },
        ],
      });
    }
    if (typeof password !== 'string') {
      return res.status(400).json({
        errors: [
          {
            title: 'Bad Request',
            detail: 'Password must be a string',
          },
        ],
      });
    }
    const user = await User.findOne({ email });
    if (!user) {
      throw new Error();
    }
    const userId = user._id;

    const passwordValidated = await bcrypt.compare(password, user.password);
    if (!passwordValidated) {
      throw new Error();
    }

    const session = await initSession(userId);

    res
      .cookie('token', session.token, {
        httpOnly: true,
        sameSite: true,
        maxAge: 1209600000,
        secure: process.env.NODE_ENV === 'production',
      })
      .json({
        title: 'Login Successful',
        detail: 'Successfully validated user credentials',
        csrfToken: session.csrfToken,
      });
  } catch (err) {
    res.status(401).json({
      errors: [
        {
          title: 'Invalid Credentials',
          detail: 'Check email and password combination',
          errorMessage: err.message,
        },
      ],
    });
  }
});

問題不在於 cookie 或本地存儲之間。 是你從來沒有真正設置過令牌!

在你的Login.js中,你應該在里面調用props.setToken(res)

axios
  .post("/api/users/login", user)
  .then((res) => {
     //Call it here
}

您還需要確保 Login 組件已傳入其道具:

export default function Login(props) {

暫無
暫無

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

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