如何在 MERN 应用中实现登录功能?
Posted
技术标签:
【中文标题】如何在 MERN 应用中实现登录功能?【英文标题】:How do I implement login functionality in a MERN app? 【发布时间】:2021-10-01 18:42:05 【问题描述】:我正在我的本地主机(前端端口 3000,后端端口 5000)上开发一个(简单易用的)笔记 Web 应用程序。我在实现用户登录功能时遇到了麻烦。我将尝试在这里提炼问题。
我的主要 App.jsx 组件有一个 LoginScreen.jsx 组件作为子组件,它在这里:
import useState, useEffect from 'react';
import Link from 'react-router-dom';
import AuthService from '../services/auth.js';
import './LoginScreen.css';
const LoginScreen = ( history ) =>
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
useEffect(() =>
if (localStorage.getItem('authToken')) history.push('/');
, [history]);
const loginHandler = async e =>
e.preventDefault();
try
const data = email, password ;
AuthService.loginUser(data).then(response =>
localStorage.setItem('authToken', response.data.token);
);
history.push('/');
catch (error)
setError(error.response.data.error);
setTimeout(() =>
setError('');
, 5000);
;
return (
<div className="login-screen">
<form
className="login-screen__form"
onSubmit=loginHandler
autoComplete="off"
>
<h3 className="login-screen__title">Login</h3>
error && <span className="error-message">error</span>
<div className="form-group">
<label htmlFor="email">Email:</label>
<input
type="email"
required
id="email"
placeholder="enter email"
value=email
onChange=e => setEmail(e.target.value)
tabIndex=1
/>
</div>
<div className="form-group">
<label htmlFor="password">
Password:' '
<Link
to="/forgotpassword"
className="login-screen__forgotpassword"
tabIndex=4
>
Forgot Password?
</Link>
</label>
<input
type="password"
required
id="password"
placeholder="enter password"
value=password
onChange=e => setPassword(e.target.value)
tabIndex=2
/>
</div>
<button type="submit" className="btn btn-primary" tabIndex=3>
Login
</button>
<span className="login-screen__subtext">
Don't have an account? <Link to="/register">Register</Link>
</span>
</form>
</div>
);
;
export default LoginScreen;
当用户点击“登录”时,应该会触发 AuthService,如下所示:
import http from '../routing/http-auth.js';
class AuthService
loginUser = data => http.post('/login', data);
registerUser = data => http.post('/register', data);
userForgotPassword = data => http.post('/forgotpassword', data);
userPasswordReset = data => http.put('/passwordreset/:resetToken', data);
export default new AuthService();
上面文件中的http是一个axios实例,如下图。
import axios from 'axios';
export default axios.create(
baseURL: 'http://localhost:5000/api/v1/auth',
headers:
'Content-type': 'application/json'
);
所以,请求被路由到后端,它到达这里:
import express from 'express';
import AuthController from './auth.controller.js';
const router = express.Router();
router.route('/register').post(AuthController.register);
router.route('/login').post(AuthController.login);
router.route('/forgotpassword').post(AuthController.forgotPassword);
router.route('/passwordreset/:resetToken').put(AuthController.passwordReset);
export default router;
然后在这里:
static login = async (req, res, next) =>
const email = req.body.email;
const password = req.body.password;
if (!email || !password)
return next(
new ErrorResponse('please provide an email and password', 400)
);
try
const user = await User.findOne( email ).select('+password');
if (!user) return next(new ErrorResponse('invalid credentials', 401));
const isMatch = await user.matchPasswords(password);
if (!isMatch) return next(new ErrorResponse('invalid credentials', 401));
sendToken(user, 200, res);
catch (error)
next(error);
;
这一切都在一个虚拟应用程序上运行,但现在,它在我的笔记应用程序中不起作用。我得到了错误:
Uncaught (in promise) TypeError: Cannot read property 'data' of undefined
at loginHandler (LoginScreen.jsx:27)
我怎样才能做到这一点?
【问题讨论】:
邮递员可以登录吗?您可以添加 sendToken 方法的代码吗?你也能展示你如何设置服务器(索引、应用程序或 server.js)吗? 邮递员也失败了...错误:请提供电子邮件和密码。 在第 25 行输入 console.log(error) - 就在 setError(error.response.data.error) 上方,我收到错误:TypeError: Cannot read property 'push' of undefined at loginHandler ( LoginScreen.jsx:26) 要去尝试一些改变...谢谢大家! Umar 然后首先尝试解决快递方面的问题。您是否添加了 express json 中间件以便它可以从请求正文中读取? 【参考方案1】:您的TypeError: Cannot read property 'data' of undefined
表示您的代码试图从未定义(null,缺失)对象中读取.data
属性。
在第 27 行,您的代码执行 setError(error.response.data.error);
因此您的错误消息意味着 error
存在但 error.response
不存在。
将 console.log(error)
放在第 27 行之前(或设置断点),这样您就可以确保理解您捕获的 error
对象。
如果错误消息是TypeError: Cannot read property 'data' of an undefined object named error.response
,那就太好了。但事实并非如此,因此您必须自己做出推断。
【讨论】:
以上是关于如何在 MERN 应用中实现登录功能?的主要内容,如果未能解决你的问题,请参考以下文章