首页 > 解决方案 > 尝试使用 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;

标签: node.jsreactjsmongodb

解决方案


如果使用 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'));

推荐阅读