英文:
React JS Redirect Upon Sign in
问题
I need my user to be redirected upon success. What I have now does not redirect but will present the success pop up message at the end of the form.
JSX 文件
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { Navigate } from 'react-router-dom';
const Login = () => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [loginStatus, setLoginStatus] = useState('');
axios.defaults.withCredentials = true;
const login = (event) => {
event.preventDefault();
axios
.post('http://localhost:5000/login', {
username: username,
password: password,
})
.then((response) => {
if (response.data.message) {
setLoginStatus(response.data.message);
} else {
setLoginStatus(response.data.username);
// 这里不能直接使用 <Navigate to="/admin/home" /> 来进行重定向
// 你需要在组件外部使用路由来进行重定向
}
})
.catch((error) => {
console.error('Error logging in:', error);
});
};
useEffect(() => {
axios
.get('http://localhost:5000/check-session')
.then((response) => {
if (response.data.loggedIn) {
// 这里也不能直接使用 <Navigate to="/admin/home" /> 来进行重定向
// 你需要在组件外部使用路由来进行重定向
}
})
.catch((error) => {
console.error('Error checking session:', error);
});
}, []);
return (
<div className='Login-page'>
<h1>Login</h1>
<form onSubmit={login}>
<button type='submit' className='btn btn-outline-primary'>
Login
</button>
</form>
{loginStatus && <p>{loginStatus}</p>}
</div>
);
};
export default Login;
Server.js (Express 文件)
const express = require('express');
const app = express();
const mysql = require('mysql');
const morgan = require('morgan');
const cors = require('cors');
const session = require('express-session');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
// Middleware
app.use(
cors({
origin: 'http://localhost:3000', // 替换为你的前端应用的 URL
methods: ['GET', 'POST', 'PUT', 'DELETE'],
credentials: true, // 允许携带凭证 (cookies)
})
);
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.json()); // 解析 JSON 请求体
app.use(express.urlencoded({ extended: true })); // 解析 URL 编码的请求体
app.use(morgan('dev')); // 使用 Morgan 记录 HTTP 请求
// 会话设置
/* 设置 Cookie 选项 */
app.use(
session({
secret: 'secretKey123',
resave: false,
saveUninitialized: false,
cookie: {
secure: false, // 如果使用 HTTPS,请将此设置为 true
maxAge: 24 * 60 * 60 * 1000, // 24 小时
},
})
);
// 路由
app.post('/login', (req, res) => {
const username = req.body.username;
const password = req.body.password;
connection.query(
'SELECT * FROM admin_users WHERE username = ? AND password = ?',
[username, password],
(error, results, fields) => {
if (error) {
console.error('Error executing MySQL query: ' + error.stack);
return res.status(500).json({ error: 'Internal Server Error' });
}
if (results.length > 0) {
req.session.username = username; // 设置会话变量为用户名
res.json({ success: true, message: 'Login successful' });
} else {
res.json({ success: false, message: 'Invalid username or password' });
}
}
);
});
app.get('/check-session', (req, res) => {
if (req.session.username) {
res.json({ loggedIn: true, user: req.session.username });
} else {
res.json({ loggedIn: false });
}
});
app.post('/check-session', (req, res) => {
console.log(req.session);
if (req.session.isLoggedIn) {
res.json({ isLoggedIn: true });
} else {
res.json({ isLoggedIn: false });
}
});
app.post('/logout', (req, res) => {
req.session.destroy((error) => {
if (error) {
console.error('Error destroying session:', error);
return res.status(500).json({ error: 'Internal Server Error' });
}
res.clearCookie('userId'); // 清除会话 cookie
res.json({ success: true, message: 'Logout successful' });
});
});
// 启动服务器
app.listen(5000, () => {
console.log('Server started on port 5000');
});
你在 JSX 文件中尝试使用 <Navigate to="/admin/home" />
来进行重定向,但这是不正确的做法。重定向应该在组件外部,例如,在路由器组件中完成。根据你的代码,你可以在登录成功后使用路由器的 history
对象来进行重定向,例如:
import { useHistory } from 'react-router-dom';
// ...
const Login = () => {
const history = useHistory();
// ...
const login = (event) => {
event.preventDefault();
axios
.post('http://localhost:5000/login', {
username: username,
password: password,
})
.then((response) => {
if (response.data.message) {
setLoginStatus(response.data.message);
} else {
setLoginStatus(response.data.username);
// 登录成功后进行重定向
history.push('/admin/home');
}
})
.catch((error) => {
console.error('Error logging in:', error);
});
};
// ...
};
同样,在检查会话后,你也可以使用 history
对象来进行重定向。这样应该能够正确实现重定向功能。
英文:
I need my user to be redirected upon success. What I have now does not redirect but will present the success pop up message at the end of the form.
JSX File
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { Navigate } from 'react-router-dom';
const Login = () => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [loginStatus, setLoginStatus] = useState('');
axios.defaults.withCredentials = true;
const login = (event) => {
event.preventDefault();
axios
.post('http://localhost:5000/login', {
username: username,
password: password,
})
.then((response) => {
if (response.data.message) {
setLoginStatus(response.data.message);
} else {
setLoginStatus(response.data.username);
return <Navigate to="/admin/home" />;
}
})
.catch((error) => {
console.error('Error logging in:', error);
});
};
useEffect(() => {
axios
.get('http://localhost:5000/check-session')
.then((response) => {
if (response.data.loggedIn) {
return <Navigate to="/admin/home" />;
// Redirect to /admin/home if already logged in
}
})
.catch((error) => {
console.error('Error checking session:', error);
});
}, []);
return (
<div className='Login-page'>
<h1>Login</h1>
<form onSubmit={login}>
<button type='submit' className='btn btn-outline-primary'>
Login
</button>
</form>
{loginStatus && <p>{loginStatus}</p>}
</div>
);
};
export default Login;
Server.js (Express file)
const express = require('express');
const app = express();
const mysql = require('mysql');
const morgan = require('morgan');
const cors = require('cors');
const session = require('express-session');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
// Middleware
app.use(cors({
origin: 'http://localhost:3000', // Replace with your frontend application's URL
methods: ["GET","POST","PUT", "DELETE"],
credentials: true, // Allow credentials (cookies)
}));
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.json()); // Parse JSON bodies
app.use(express.urlencoded({ extended: true })); // Parse URL-encoded bodies
app.use(morgan('dev')); // Use Morgan for logging HTTP requests
// Session setup
/* Set Cookie Settings */
app.use(
session({
secret: 'secretKey123',
resave: false,
saveUninitialized: false,
cookie: {
secure: false, // Set this to true if you use HTTPS
maxAge: 24 * 60 * 60 * 1000, // 24 hours
},
})
);
// Routes
app.post('/login', (req, res) => {
const username = req.body.username;
const password = req.body.password;
connection.query(
'SELECT * FROM admin_users WHERE username = ? AND password = ?',
[username, password],
(error, results, fields) => {
if (error) {
console.error('Error executing MySQL query: ' + error.stack);
return res.status(500).json({ error: 'Internal Server Error' });
}
if (results.length > 0) {
req.session.username = username; // Set session variable to the username
res.json({ success: true, message: 'Login successful' });
} else {
res.json({ success: false, message: 'Invalid username or password' });
}
}
);
});
app.get('/check-session', (req, res) => {
if (req.session.username) {
res.json({ loggedIn: true, user: req.session.username });
} else {
res.json({ loggedIn: false });
}
});
app.post('/check-session', (req, res) => {
console.log(req.session)
if (req.session.isLoggedIn) {
res.json({ isLoggedIn: true });
} else {
res.json({ isLoggedIn: false });
}
});
app.post('/logout', (req, res) => {
req.session.destroy((error) => {
if (error) {
console.error('Error destroying session:', error);
return res.status(500).json({ error: 'Internal Server Error' });
}
res.clearCookie('userId'); // Clear the session cookie
res.json({ success: true, message: 'Logout successful' });
});
});
// Start the server
app.listen(5000, () => {
console.log('Server started on port 5000');
});
I have tried using Navigate to redirect but it does nothing. At this point anything would help. Ive tried following a Youtube guide but I ran into an issue with getting the session started. Now I have the session started but it fails to redirect.
答案1
得分: 0
在最新版本的react-router-dom(v6)中,不能像这样导航。
您需要按照以下步骤操作:
从"react-router-dom"中导入{ useNavigate }。
现在在函数中,您必须以以下方式创建它的实例。
const navigate = useNavigate();
现在,您可以使用此导航进行重定向。
只需将您的return <Navigate to="/admin/home" />
替换为navigate("/admin/home")
。
您可以参考此链接获取更多信息:https://reactrouter.com/en/main/hooks/use-navigate
英文:
You can't Navigate like this in the latest version of react-router-dom (v6).
You have to follow these steps:
import { useNavigate } from "react-router-dom";
Now in the function, you have to create instance of it in the following way.
const navigate = useNavigate();
and, now you can redirect using this navigate.
Just replace your return <Navigate to="/admin/home" />
with the navigate("/admin/home)
You can refer this for more info: https://reactrouter.com/en/main/hooks/use-navigate
答案2
得分: 0
在你的代码中,首先检查 "response.data.message"。
if (response.data.message) {
setLoginStatus(response.data.message);
}
如果存在消息,你只是设置了登录状态,什么都不做!
在查看后端代码时,无论是有效的用户/密码还是无效的用户/密码,你总是返回一个消息。
if (results.length > 0) {
req.session.username = username; // 将会话变量设置为用户名
res.json({ success: true, message: '登录成功' });
} else {
res.json({ success: false, message: '用户名或密码无效' });
}
这就是为什么它什么都不做。你需要检查一些唯一的东西,例如 "success",并确保没有 "error",然后进行重定向。
英文:
In your code, you're checking first for "response.data.message"
if (response.data.message) {
setLoginStatus(response.data.message);
}
And if there is a message, you just set the login status and do nothing!
When looking to Backend code, you're always returning a message either it is a valid user/password or not.
if (results.length > 0) {
req.session.username = username; // Set session variable to the username
res.json({ success: true, message: 'Login successful' });
} else {
res.json({ success: false, message: 'Invalid username or password' });
}
This is why it does nothing. You need to check for something unique, "success" for example and also check that there is no "error", then redirect.
答案3
得分: 0
确实如@Maulik所说,你应该使用useNavigate
的navigate
实例,而不是<Navigate to="/admin/home" />
。
你需要向Axios的post请求添加Content-type头。此外,axios已经有错误处理,因此API的失败响应将直接进入catch块。所以,
const login = (event) => {
event.preventDefault();
axios
.post(
"http://localhost:5000/login",
{
username: username,
password: password,
},
{
headers: { "Content-Type": "application/json" },
}
)
.then((response) => {
setLoginStatus(response.data.username);
navigate("/admin/home", { replace: true });
})
.catch((error) => {
error?.response
? setLoginStatus(error.response.data.message)
: setLoginStatus("No server response..");
});
};
英文:
It's true what @Maulik said you should use the navigate
instance of useNavigate
instead of <Navigate to="/admin/home" />
.
You need to add Content-type header to Axios post. Additionally, axios already has error handling, so failed responses from your API will fall directly into the catch block. So,
const login = (event) => {
event.preventDefault();
axios
.post(
"http://localhost:5000/login",
{
username: username,
password: password,
},
{
headers: { "Content-Type": "application/json" },
}
)
.then((response) => {
setLoginStatus(response.data.username);
navigate("/admin/home", { replace: true });
})
.catch((error) => {
error?.response
? setLoginStatus(error.response.data.message)
: setLoginStatus("No server response..");
});
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论