node.js - 尝试使用 api 验证 NODE + REACT 时出现错误请求 (400)
问题描述
我使用 NodeJS 制作了一个 API 来注册和登录用户并生成令牌。将 API 与 POSTMAN 一起使用,它工作得很好,但是当我添加 React 并尝试使用用户登录时,我收到一个错误( 400 )错误请求。尝试调试它,我发现它已由前端传递但服务器没有接收到数据。所以我想问题出在服务器端。
我在这里上传的所有代码:https ://github.com/drrh12/auth-login 我将发布以下图片:
NODE JS 认证文件。
const router = require('express').Router();
const User = require('../model/User');
const{registerValidation, loginValidation} = require('../validation');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
router.post('/register', async (req, res) => {
const { error } = registerValidation(req.body);
if (error) return res.status(400).send(error.details[0].message);
//Check user in data base
const emailExist = await User.findOne({
email: req.body.email
});
if(emailExist) return res.status(400).send('Email already exist');
//Hash Pass
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(req.body.password, salt);
//Creating a new user
const user = new User({
name: req.body.name,
email: req.body.email,
password: hashedPassword
});
try{
const savedUser = await user.save();
res.send(savedUser);
}catch(err){
res.status(400).send(err)
}
})
router.post('/login', async (req, res) => {
const { error } = loginValidation(req.body);
if (error) return res.status(400).send(error.details[0].message);
const user = await User.findOne({ email: req.body.email });
if(!user) return res.status(400).send('Email or pass is wrong');
const validPass = await bcrypt.compare(req.body.password, user.password);
if(!validPass) return res.status(400).send('Invalid pass')
//Token
const token = jwt.sign({_id: user.id}, process.env.TOKEN_SECRET);
res.header('auth-token', token).send(token);
res.send('Logged in');
});
module.exports = router;
验证模式
const Joi = require('@hapi/joi');
const registerValidation = data => {
const schema = Joi.object({
name: Joi.string()
.min(3)
.required(),
email: Joi.string()
.min(3)
.required()
.email(),
password: Joi.string()
.min(3)
.required()
});
return schema.validate(data);
};
const loginValidation = data => {
const schema = Joi.object({
email: Joi.string()
.min(3)
.required(),
password: Joi.string()
.min(3)
.required()
});
return schema.validate(data);
};
module.exports.registerValidation = registerValidation;
module.exports.loginValidation = loginValidation;
解决方案
如果使用 axios 是一个选项,您可以进行这些更改并尝试。
1-) 使用 npm i axios 安装 axios
2-) 将登录页面更改为使用 axios。使用 axios,它的代码更少而且更干净。登录.js
import React, { Component } from "react";
import { Form, FormGroup, Label, Input, Button, Alert } from "reactstrap";
import Header from "../components/Header";
import axios from "axios";
export default class Login extends Component {
constructor() {
super();
this.state = {
message: ""
};
}
signIn = async () => {
const data = { email: this.email, password: this.password };
console.log(data);
try {
const response = await axios.post(
"http://localhost:5000/api/user/login",
data
);
console.log(response.data);
localStorage.setItem("token", response.data);
alert("SUCCESS");
} catch (err) {
console.log(err);
this.setState({ message: err.message });
}
};
render() {
return (
<div className="col-md-6">
<Header title="ReactJS Login" />
<hr className="my-3" />
{this.state.message && (
<Alert color="danger" className="text-center">
{this.state.message}
</Alert>
)}
<Form>
<FormGroup>
<Label for="email">Email</Label>
<Input
type="text"
name="email"
id="email"
onChange={e => (this.email = e.target.value)}
placeholder="Inform the email"
/>
</FormGroup>
<FormGroup>
<Label for="password">Senha</Label>
<Input
type="password"
name="password"
id="password"
onChange={e => (this.password = e.target.value)}
placeholder="Inform the password"
/>
</FormGroup>
<Button color="primary" block onClick={this.signIn}>
Entrar
</Button>
</Form>
</div>
);
}
}
3-) 最后更改 index.js 代码以防止与 cors 相关的问题。
const express = require('express');
const app = express();
const mongoose = require('mongoose');
const dotenv = require('dotenv');
const authRoute = require('./routes/auth');
const dashRoute = require('./routes/dashboard');
dotenv.config();
mongoose.connect(
process.env.DB_CONNECT,
{useNewUrlParser: true},
() => console.log('connected to db')
);
//Middleware
app.use(express.json());
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS"
);
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization"
);
res.header("Access-Control-Expose-Headers");
next();
});
// Router middlewares
app.use('/api/user', authRoute);
app.use('/api/dashboard', dashRoute);
app.listen(5000, () => console.log('Server up and running'));
推荐阅读
- qt - 如何调整 QDockWidget 的大小
- uikit - 如何将不在根层次结构中的 SwiftUI 视图呈现为 UIImage?
- textmate - 在 Textmate 中保存时出错 - 将现有文件保存在现有文件夹中时,“文件名”没有父文件夹
- ffmpeg - ffmpeg 覆盖 v4l2-ctl 配置 -> 如何将真正的原始设备复制到网络?
- powershell - 如何使用 PowerShell 从文件名中删除句点?
- java - 如何获取 OrdImage 的库
- r - 如何在 R 中创建一个数据框,其列计算引用了前一行中自己的值?
- sql - 用于合并结果的 Pivot 或 Group 函数
- python - Keras多输出numpy转换
- excel - 转置虚拟变量