如何在React中通过自定义API验证数据库内的邮箱与密码
问题描述
我想用自定义API验证登录时输入的邮箱和密码是否与数据库中注册的信息一致,但现在无论输入什么内容,前端都会输出“Login”。我需要仅当信息匹配时才显示该内容。
React登录组件代码
import { useState } from 'react'; import Button from 'react-bootstrap/Button'; import Form from 'react-bootstrap/Form'; import { Link } from "react-router-dom" const Login = () => { const [email, setEmail] = useState('') const [password, setPassword] = useState('') const handleSubmit = (e) => { e.preventDefault() const info = {email, password} fetch('http://localhost:3333/login/', { mode: 'no-cors', method: 'POST', headers: { "Content-Type": "application/json" }, body: JSON.stringify(info) }).then((response) => { console.log(response) console.log("login") }).catch(() => { console.log("NO") }) } return ( <div className="all "> <div className='button d-flex justify-content-center '> <Link to="/" className="text-center btn btn-secondary btn-lg m-4">Login</Link> <Link to="/register" className="text-center btn btn-secondary btn-lg m-4">Register</Link> </div> <p className='text-center'>Sign With:</p> <div className="container d-flex justify-content-center"> <Form onSubmit={handleSubmit}> <Form.Group className="mb-3" controlId="formBasicEmail"> <Form.Label>Email address</Form.Label> <Form.Control type="email" value = {email} onChange={(e) => setEmail (e.target.value)} placeholder="Enter email" required/> <Form.Text className="text-muted"> We'll never share your email with anyone else. </Form.Text> </Form.Group> <Form.Group className="mb-3" controlId="formBasicPassword"> <Form.Label>Password</Form.Label> <Form.Control type="password" value = {password} onChange={e => setPassword(e.target.value)} placeholder="Password" /> </Form.Group> <Form.Group className="mb-3" controlId="formBasicCheckbox"> <Form.Check type="checkbox" label="Check me out" /> </Form.Group> <Button variant="primary" type="submit"> Submit </Button> </Form> </div> </div> ); } export default Login;
后端API代码
const { PrismaClient } = require("@prisma/client"); const prisma = new PrismaClient(); const bcrypt = require('bcrypt'); module.exports = { async createUser(req, res) { try { const { firstName, lastName, email, password, age, role } = req.body const salt = await bcrypt.genSalt(); console.log(salt) const hash = await bcrypt.hash(password, salt) console.log(hash) const verifyemail = await prisma.UserInfo.findUnique({ where: { email } }) if (verifyemail) { return res.json({ error: "there is a email with the same name, please change." }) } const user = await prisma.UserInfo.create({ data: { firstName: firstName, lastName: lastName, email: email, password: hash, age: age, role: role } }); return res.json(user) } catch (error) { return res.json({ error }) } }, async login(req, res) { try { const {email, password} = req.body const user = await prisma.UserInfo.findUnique({ where: { email : req.body.email } }) if(user) { const match = await bcrypt.compare(password, user.password) if(match) { return res.send("login") } else { return res.send("There is something wrong with your password") } } } catch (error) { return res.json({ error }) } } }
解决方案
问题出在前端代码的两个核心问题,同时后端也有一处逻辑补全点:
移除
no-cors模式mode: 'no-cors'会让浏览器完全限制读取响应内容,即使后端返回了正确结果,前端也无法获取。直接删除该配置即可,如果后端存在跨域问题,需要在后端添加CORS中间件(比如Express的cors包)。根据后端响应结果判断登录状态
当前代码不管后端返回什么,都会直接打印“login”。需要先解析后端的响应文本,再根据返回值执行对应逻辑。
修改后的前端handleSubmit函数:
const handleSubmit = (e) => { e.preventDefault() const info = {email, password} fetch('http://localhost:3333/login/', { method: 'POST', headers: { "Content-Type": "application/json" }, body: JSON.stringify(info) }) .then(response => response.text()) .then(data => { console.log(data) if (data === "login") { console.log("Login") // 这里可添加登录成功后的逻辑,比如跳转首页、存储用户信息等 } else { console.log(data) // 输出错误提示,比如密码错误或邮箱未注册 } }) .catch(error => { console.log("请求出错:", error) }) }
- 后端补充邮箱不存在的响应逻辑
当前后端如果遇到未注册的邮箱,不会返回任何响应,会导致前端请求超时。补充如下逻辑:
async login(req, res) { try { const {email, password} = req.body const user = await prisma.UserInfo.findUnique({ where: { email : req.body.email } }) if(user) { const match = await bcrypt.compare(password, user.password) if(match) { return res.send("login") } else { return res.send("密码错误") } } else { return res.send("该邮箱未注册") } } catch (error) { return res.json({ error: error.message }) } }
内容的提问来源于stack exchange,提问作者Matheus Coppi
相关产品推荐
相关产品推荐

