React JS 如何使用自定义reactHooks正确设置Cookie?

问题描述 投票:0回答:1

我正在创建网站的登录功能,但在使用后端的令牌设置 Cookie 时遇到问题。令牌已正确返回,并在 UserContext 中设置用户,但是令牌要存储在浏览器 Cookie 中的部分(例如在浏览器开发人员选项

Application
选项卡中查看时)未显示或未显示放。我不知道问题出在
Login.jsx
还是
useStorage.js
。以下是当前代码:

./src/hooks/useStorage.js

import { useCallback, useEffect, useState } from 'react';
import Cookies from 'js-cookie';

function useLocalStorage(key, defaultValue) {
    return useStorage(key, defaultValue, window.localStorage);
};

function useSessionStorage(key, defaultValue) {
    return useStorage(key, defaultValue, window.sessionStorage);
};

function useCookiesStorage(key, defaultValue, options) {
    return useStorage(key, defaultValue, null, options);
};

function useStorage(key, defaultValue, storageObject, options) {
    const [value, setValue] = useState(() => {
        if (storageObject) {
            const jsonValue = storageObject.getItem(key);
            if (jsonValue != null) return JSON.parse(jsonValue);
        } else {
            const cookieValue = Cookies.get(key);
            if (cookieValue != null) return JSON.parse(cookieValue);
        }

        if (typeof defaultValue === "function") {
            return defaultValue();
        } else {
            return defaultValue;
        }
    });

    useEffect(() => {
        if (value === undefined) {
            if (storageObject) {
                return storageObject.removeItem(key);
            } else {
                return Cookies.remove(key, options);
            }
        }

        const jsonValue = JSON.stringify(value);
        if (storageObject) {
            storageObject.setItem(key, jsonValue);
        } else {
            Cookies.set(key, jsonValue, options);
        }
    }, [key, value, storageObject, options]);

    const remove = useCallback(() => {
        setValue(undefined);
    }, []);

    return [value, setValue, remove];
};

export {
    useLocalStorage,
    useSessionStorage,
    useCookiesStorage
};

./src/pages/Login.jsx

import '../assets/css/login.css';
import { Button, Col, Container, Form, Image, InputGroup, Row, Stack } from 'react-bootstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { useContext, useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { GetUser, SignIn } from '../utils/Auth';
import Swal from 'sweetalert2';
import { useCookiesStorage } from '../hooks/useStorage';
import UserContext from '../UserContext';

function Login() {
    const { setUser } = useContext(UserContext);
    const navigate = useNavigate();
    const [uidValue, setUidValue] = useState('');
    const [upassValue, setUpassValue] = useState('');
    const [,setToken] = useCookiesStorage('__Secure-auth.session-token', null, {httpOnly: true, secure: true, sameSite: 'Strict'});

    async function LoginUser(e) {
        e.preventDefault();

        Swal.fire({
            title: 'Logging in',
            didOpen: () => {
                Swal.showLoading();
            },
            text: 'Please wait',
            showConfirmButton: false,
            allowOutsideClick: false
        });
        const response = await SignIn(uidValue, upassValue); // Returns response message and token
        
        if (!response || !response.token) {
            Swal.close();
            Swal.fire({
                title: `${response.message}!`,
                icon: 'error',
                text: 'Try again',
                timer: 2000,
                timerProgressBar: false,
                showConfirmButton: false,
                allowOutsideClick: false
            });
        }
        else {
            setToken(response.token); // Set the Cookie '__Secure-auth.session-token'
            const user = await GetUser(response.token); // returns user details
            
            if (!user || !user._id) {
                Swal.close();
                Swal.fire({
                    title: `${response.message}!`,
                    icon: 'error',
                    text: 'Try again',
                    timer: 2000,
                    timerProgressBar: false,
                    showConfirmButton: false,
                    allowOutsideClick: false
                });
            }
            else {
                Swal.close();
                Swal.fire({
                    title: 'Login successful!',
                    icon: 'success',
                    text: 'Redirecting to dashboard, please wait...',
                    timer: 2000,
                    timerProgressBar: false,
                    showConfirmButton: false,
                    allowOutsideClick: false
                })
                .then((result) => {
                    if (result.dismiss === Swal.DismissReason.timer) {
                        setUidValue('');
                        setUpassValue('');
                        setUser({ // Sets user context with details from fetch request
                            uid: user._id,
                            user: user.username,
                            role: user.role
                        });
                        navigate('/dashboard');
                    }
                });
            }
        }
    };

    return (...rest of code);
};

export default Login;

我希望有人能帮助我解决我做错的事情,我对 React JS 还很陌生,并且通过基于项目的学习进行学习。

javascript reactjs react-hooks js-cookie
1个回答
0
投票

如果您在使用

httpOnly
设置具有
secure
js-cookie
标志的 cookie 时遇到问题,请注意,由于安全原因,
httpOnly
cookie 无法通过 JavaScript 进行管理。

  1. 删除
    httpOnly
    以进行测试:暂时删除
    httpOnly
    标志,以确保 cookie 已设置并在浏览器的开发人员工具中可见。
  2. 检查 HTTPS:如果使用
    secure
    标志,请确保您正在通过 HTTPS 运行应用程序。
  3. 验证后端设置:确保您的后端使用所需的标志正确设置 cookie。

以下是在 Express.js 中设置 cookie 的方法:

res.cookie('__Secure-auth.session-token', 令牌, { httpOnly:正确, secure: process.env.NODE_ENV === '生产', // 在生产中使用 true SameSite:“严格” });

为了进行测试,请根据需要调整标志以验证功能。

© www.soinside.com 2019 - 2024. All rights reserved.