Я пытаюсь изучить приложение React JS и Springboot, и при перезапуске Java я аннулирую tokenVersion (метку времени в полезной нагрузке jwt, но не фактический токен) в токене jwt.
при перезапуске Java и если я пытаюсь перезагрузить страницу реагирования или навигацию по Spring Security, выдается ошибка 403.
используя ответ, который я проверяю, и пытаюсь заставить пользователя выйти из системы и попытаться использовать перехватчик SignOut для очистки состояния или сеанса, но я получаю ошибку перехватчика реакции.
Я пробовал много способов из чата gpt, но ни один из них не дал решения.
это мои следующие коды реакции:
1. Конечная точкаConfig.js
import axios from 'axios';
import useSetupInterceptors from '../util/useSetupInterceptors'
const config = window.APP_CONFIG;
const endPointURLIP = config.endPointIP;
const defaultUrl = "localhost";
if (!endPointURLIP)
endPointURLIP = defaultUrl;
//Retrieving Token from the cookie which saved while login.
const getTokenFromCookie = () => {
const cookies = document.cookie.split(';').map(cookie => cookie.trim());
for (const cookie of cookies) {
if (cookie.startsWith('_auth=')) {
const tokenCookie = cookie.split('=');
if (tokenCookie.length === 2) {
return tokenCookie[1];
}
}
}
return null; // Token not found in cookies
};
const authToken = getTokenFromCookie();
const getAxiosHeader = () => {
const API_BASE_URL = 'http://'+endPointURLIP+':9081';
const AUTHENTICATION_HEADER_TOKEN = authToken ? `Bearer ${authToken}` : null;
return axios.create({
baseURL: API_BASE_URL,
headers: {
Authorization: AUTHENTICATION_HEADER_TOKEN,
},
});
};
const authAxiosHeader = getAxiosHeader();
useSetupInterceptors(authAxiosHeader);
const endpointConfig = {
a: 'http://'+endPointURLIP+':9081',
HISTORY_ENDPOINT: '/demo/history',
AUTHENTICATION_HEADER_TOKEN: authToken ? `Bearer ${authToken}` : null,
AUTHENTICATION_HEADER:authAxiosHeader,
};
export default endpointConfig;
2. используйтеSetupInterceptors.js
import { useEffect } from 'react';
import { useSignOut } from 'react-auth-kit';
const useSetupInterceptors = ({ axiosInstance }) => {
const signOut = useSignOut();
useEffect(() => {
const interceptor = axiosInstance.interceptors.response.use(
(response) => response,
(error) => {
if (error.response && error.response.status === 403) {
alert('Request failed with status code 403:', error.message);
handleLogout();
}
return Promise.reject(error);
}
);
const handleLogout = () => {
window.location.href = '/';
signOut();
};
return () => {
axiosInstance.interceptors.response.eject(interceptor);
};
}, [axiosInstance, signOut]);
};
export default useSetupInterceptors;
3. Демосервис.js
import axios from 'axios';
import endpointConfig from './EndpointConfig';
class DemoService {
constructor() {
this.baseUrl = endpointConfig.API_BASE_URL;
this.getHistoryEndpoint = endpointConfig.HISTORY_ENDPOINT;
this.axiosHeader = endpointConfig.AUTHENTICATION_HEADER;
}
async getDemoHistory() {
try {
const response = await this.axiosHeader.get(`${this.getHistoryEndpoint}`);
const configData = response.data;
return configData;
} catch (error) {
console.info('Error retrieving data:'+error);
}
}
}
export default new DemoService();
Демоистория.js
import React, { Component } from 'react';
import { DataTable } from 'primereact/datatable';
import { Column } from 'primereact/column';
import DemoService from '../services/DemoService';
class DemoHistory extends Component {
constructor(props) {
super(props);
this.state = {
resultFromController: [],
isLoading: true,
};
}
componentDidMount() {
this.getDemoHistory();
}
getDemoHistory = () => {
DemoService.getDemoHistory()
.then((res) => {
this.setState({ resultFromController: res, isLoading: false });
})
.catch((error) => {
console.error('Error fetching Demo history:', error);
this.setState({ isLoading: false });
});
};
render() {
const { resultFromController, isLoading } = this.state;
if (isLoading) {
return <div>Loading...</div>;
}
return (
<div>
<h1>Demo History</h1>
<DataTable value = {resultFromController}>
<Column field = "fromUser" header = "From User" />
<Column field = "toUser" header = "To User" />
</DataTable>
</div>
);
}
}
export default DemoHistory;
Приложение.js
import React from 'react';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import { AuthProvider, RequireAuth } from 'react-auth-kit';
import DemoHistory from './components/DemoHistory';
function App() {
return (
<AuthProvider
authType = {"cookie"}
authName = {"_auth"}
cookieDomain = {window.location.hostname}
cookieSecure = {false}
>
<div>
<h2 className = "header_name">Demo</h2>
<BrowserRouter>
<Routes>
<Route path = "DemoHistory" element = {<RequireAuth loginPath = "/"><DemoHistory /></RequireAuth>} />
</Routes>
</BrowserRouter>
</div>
</AuthProvider>
);
}
export default App;
Логин.js
import React, { useState } from "react";
import { Button, Form } from 'react-bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';
import { useNavigate } from "react-router-dom";
import { useAuthHeader, useSignIn ,useSignOut } from "react-auth-kit";
import LoginService from "../services/LoginService";
export default function Login() {
const [loginId, setLoginId] = useState("");
const [password, setPassword] = useState("");
const loginService = new LoginService();
const navigate = useNavigate();
const { setAuth, setHeader } = useAuthHeader();
const signIn = useSignIn();
const [loginStatus, setLoginStatus] = useState(null);
function validate() {
return loginId.length > 0 && password.length > 0;
}
async function submit(event) {
try{
event.preventDefault();
loginService.setLoginId(loginId);
loginService.setPassword(password);
const result = await loginService.validateLogin(loginId,password);
if (result && result.response === "success") {
signIn({
token: result.token,
expiresIn: 24*60*60,//24 hours
tokenType: "Bearer",
authState: { username: "admin" },
});
window.location.href = "/history";
} else {
setLoginStatus("invalid");
console.info("Login failed...");
}
}catch(error){
setLoginStatus("invalid");
console.info("Error While login."+error);
}
}
return (
<form
name = "vishing_form"
method = "post"
className = "login_tab_form"
onSubmit = {submit}
>
<p align = "center" style = {{ fontWeight: 'bolder', fontSize: '18px', fontFamily: 'helvetica' }}>
RedShift Login
</p>
<div>
<label>Login ID</label>
<input className = "loginTextField"
autoFocus
type = "text"
value = {loginId}
onChange = {(e) => setLoginId(e.target.value)}
/>
</div>
<div>
<label>Password</label>
<input className = "loginTextField"
type = "password"
value = {password}
onChange = {(e) => setPassword(e.target.value)}
/>
</div>
{loginStatus === "invalid" && (
<p>
Invalid credentials. Please try again.
</p>
)}
<div>
<button
id = "submit"
type = "submit"
name = "login"
className = "submitBtn"
disabled = {!validate()}
>
Login
</button>
</div>
</div>
</form>
);
}
ошибка:
Compiled with problems:
ERROR
[eslint]
src\services\EndpointConfig.js
Line 38:3: React Hook "useSetupInterceptors" cannot be called at the top level. React Hooks must be called in a React function component or a custom React Hook function react-hooks/rules-of-hooks
я пытаюсь изучить реакцию js, пожалуйста, помогите, как решить эту проблему или какой-либо лучший способ справиться с управлением сеансом и обработкой закрытия браузера
Спасибо
@DrewReese на самом деле файл EndpointConfig.js содержит объявление URL-адреса конечной точки, а также кадрирование заголовка axios с токеном jwt
Хорошо, это нормально… но ничего из этого не является кодом React, поэтому он не может использовать перехватчик React. Если useSetupInterceptors — это то, что вы хотите использовать для установки/настройки перехватчиков Axios, вам нужно будет сделать это в React-land, и если вам нужна дополнительная помощь с этим отсюда, нам нужно будет увидеть ваш код React, следовательно, полный минимальный воспроизводимый пример соответствующего кода, с которым вы работаете.
теперь добавлено больше кода, моя цель состоит в том, чтобы при перезапуске приложения (Java) необходимо было заставить пользователя выйти из системы и очистить сеансы, по этой причине я пытаюсь использовать перехватчик реакции SignOut на основе ответа Axios
@DrewReese, я не могу открыть диалоговое окно, братан, из useSetupInterceptors
Похоже, это новая/отличающаяся проблема/проблема, о которой идет речь в этом посте. Предпочтительно создать новую публикацию SO, посвященную новой проблеме, по которой вы просите помощи. Если вы создадите новый пост, не стесняйтесь написать мне здесь в комментарии со ссылкой на пост, и я смогу посмотреть, когда он будет доступен, в противном случае вам повезет, если вы привлечете больше внимания к вашей проблеме и получите помощь быстрее, чем спрашиваю об этом здесь, в комментариях.
окей, братан, я создам новый





Вы не можете вызывать перехватчики React вне компонентов React и пользовательских перехватчиков React. Вы можете переместить вызов useSetupInterceptors в свой код React.
Вот пример использования локального компонента, который отображается внутри AuthProvider, чтобы он мог вызывать крючок useSetupInterceptors, а крючок useSetupInterceptors мог ссылаться на крючок useSignOut из `react-auth-kit';
Конечная точкаConfig.js
import axios from 'axios';
import useSetupInterceptors from '../util/useSetupInterceptors';
const config = window.APP_CONFIG;
const endPointURLIP = config.endPointIP;
const defaultUrl = "localhost";
if (!endPointURLIP) {
endPointURLIP = defaultUrl;
}
const getTokenFromCookie = () => {
const [, token = null] = document.cookie
.split(";")
.map(cookie => cookie.trim().split(" = "))
.find(([key, value]) => key === "_auth") ?? [];
return token;
};
const authToken = getTokenFromCookie();
const getAxiosInstance = () => {
const API_BASE_URL = 'http://' + endPointURLIP + ':9081';
const AUTHENTICATION_HEADER_TOKEN = authToken ? `Bearer ${authToken}` : null;
return axios.create({
baseURL: API_BASE_URL,
headers: {
Authorization: AUTHENTICATION_HEADER_TOKEN,
},
});
};
export const authAxiosInstance = getAxiosInstance(); // <-- export for app usage
const endpointConfig = {
a: 'http://'+endPointURLIP+':9081',
HISTORY_ENDPOINT: '/demo/history',
AUTHENTICATION_HEADER_TOKEN: authToken ? `Bearer ${authToken}` : null,
AUTHENTICATION_HEADER: authAxiosInstance,
};
export default endpointConfig;
import React from 'react';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import { AuthProvider, AuthOutlet } from 'react-auth-kit';
import DemoHistory from './components/DemoHistory';
import useSetupInterceptors from '../util/useSetupInterceptors';
import { authAxiosInstance } from './EndpointConfig';
const SetupAxios = () => {
useSetupInterceptors(authAxiosInstance);
return null;
};
function App() {
return (
<AuthProvider
authType = {"cookie"}
authName = {"_auth"}
cookieDomain = {window.location.hostname}
cookieSecure = {false}
>
<BrowserRouter>
<SetupAxios />
<div>
<h2 className = "header_name">Demo</h2>
<Routes>
<Route element = {<AuthOutlet fallbackPath='/' />}>
<Route path = "DemoHistory" element = {<DemoHistory />} />
</Route>
...
</Routes>
</div>
</BrowserRouter>
</AuthProvider>
);
}
export default App;
это работает, и я пытаюсь открыть диалоговое окно из useSetupInterceptors, но оно не работает. const useSetupInterceptors = (authAxiosHeader) => {const [showDialog, setShowDialog] = useState(false); if (error.response && error.response.status === 403) { alert("вызов") setShowDialog(true); } return ( <> <Dialogvisible = {showDialog} header = "Expired" onHide = {handleLogoutButtonClick} draggable = {false} > <h5 style = {{marginTop: '3rem' }}>войдите снова.</h5> </Диалог> </> );
@HarishMahi Что такое error в useSetupInterceptors? Похоже, у вас возникли непреднамеренные побочные эффекты при попытке открыть предупреждение браузера, поставить в очередь обновление состояния и вернуть немного JSX? Немного непонятно, что вы делаете в этом коде в комментарии. Имеет ли это отношение к вашему сообщению, в котором вы пытаетесь создать экземпляры перехватчиков Axios? Похоже, это дополнительный вопрос/проблема для другого поста.
это следующий вопрос, брат, можно ли вернуть jsx из useSetupInterceptors вместо прямого перенаправления пользователя, я хочу показать всплывающее окно или диалоговое окно, и я попробовал, но он не открывается
Вы не можете вызывать перехватчики React вне функциональных компонентов React или пользовательских перехватчиков. Однако я не вижу в вашем посте никакого кода React, кроме хука и файла
useSetupInterceptors. Можете ли вы отредактировать , чтобы включить более полный минимально воспроизводимый пример?