我有一个身份验证上下文提供程序,其中包含令牌和角色的状态变量以及登录和注销函数。我无法让注销函数工作。在我单击调用注销函数的链接后,我仍然可以导航到受保护的页面。我控制退出角色和令牌,它仍然显示它们已填充。在我执行刷新后,它会清除它们并强制我登录。
下面是我的useAuth.js:
import { createContext, useContext, useMemo } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import { useSessionStorage } from './useSessionStorage';
import { authenticateUser } from '../utils/APIFunctions';
const AuthContext = createContext(undefined);
export const AuthProvider = ({ children }) => {
const [token, setToken] = useSessionStorage('token', null);
const [role, setRole] = useSessionStorage('userRole', null);
const navigate = useNavigate();
const login = async (data) => {
const password = data.password;
const navigateTo = data.navigateTo;
const roles = data.roles;
// check this password in the DB
let error = '';
const result = await authenticateUser(password);
const authLevel = result?.data[0]?.auth_level;
let theRole;
switch (authLevel) {
case 99:
theRole = 'SuperAdmin';
break;
case 1:
theRole = 'User';
break;
case 2:
theRole = 'Admin';
break;
case 3:
theRole = 'Regulator';
break;
case 4:
theRole = 'QC';
break;
default:
theRole = 'none';
}
setRole(theRole);
if (result?.status === 200 && authLevel > 0) {
// this is a valid password
if (roles.includes(theRole)) {
// they are allowed to access the page they are attempting to access
const time = Date.now();
setToken({ token: password + '-' + time });
navigate(navigateTo);
} else {
// show unauthorized message/page
error = 'You do not have access to this page.';
}
} else {
if (result.data.name === 'ConnectionError') {
error = 'Unable to connect to database.';
} else if (result?.data?.ReturnValue === 0) {
} else {
error = 'Error logging into Scheduler.';
}
}
return error;
};
const logout = (redirect = true) => {
sessionStorage.clear();
setToken(null);
setRole(null);
if (redirect) {
navigate('/', { replace: true });
}
location.reload(); // i would like to remove this, the hard refresh causes a white page until the app reloads
};
const value = useMemo(
() => ({
token,
role,
login,
logout,
}),
[token, role]
);
return (
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
);
};
export const useAuth = () => {
return useContext(AuthContext);
};
然后是我的ProtectedRoute.js,它检查并验证令牌和角色:
import { Navigate, useLocation } from 'react-router-dom';
import { useAuth } from '../../hooks/useAuth';
import { Roles } from './Roles';
export const ProtectedRoute = ({ children, roles }) => {
const { token, role } = useAuth();
console.log({ token, role });
const location = useLocation();
if (
!token ||
(!roles.includes(Roles.Everyone) && !roles.includes(role))
) {
// user is not authenticated
return (
<Navigate
to={'/login'}
state={{ from: location, roles }} // <-- pass in route state
replace
/>
);
}
return children;
};
下面是useSessionStorage.js:
import { useState } from 'react';
export const useSessionStorage = (keyName, defaultValue) => {
const [storedValue, setStoredValue] = useState(() => {
try {
const value = window.sessionStorage.getItem(keyName);
if (value) {
return JSON.parse(value);
} else {
if (defaultValue) {
window.sessionStorage.setItem(
keyName,
JSON.stringify(defaultValue)
);
}
return defaultValue;
}
} catch (err) {
return defaultValue;
}
});
const setValue = (newValue) => {
if (newValue) {
try {
window.sessionStorage.setItem(
keyName,
JSON.stringify(newValue)
);
} catch (err) {}
setStoredValue(newValue);
}
};
return [storedValue, setValue];
};
1条答案
按热度按时间wswtfjt71#
更新
useSessionStorage()
中setValue
的代码,以便正确处理错误值。可能取决于您的特定使用情形,但类似于: