You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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
            })
        }
    }
}
解决方案

问题出在前端代码的两个核心问题,同时后端也有一处逻辑补全点:

  1. 移除no-cors模式
    mode: 'no-cors'会让浏览器完全限制读取响应内容,即使后端返回了正确结果,前端也无法获取。直接删除该配置即可,如果后端存在跨域问题,需要在后端添加CORS中间件(比如Express的cors包)。

  2. 根据后端响应结果判断登录状态
    当前代码不管后端返回什么,都会直接打印“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)
    })
}
  1. 后端补充邮箱不存在的响应逻辑
    当前后端如果遇到未注册的邮箱,不会返回任何响应,会导致前端请求超时。补充如下逻辑:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 11:55:40