如何解决身份验证 POST http://localhost:3000/api/users/register 400错误请求MERN 应用程序
我正在制作一个具有注册和登录功能的 MERN 应用程序。当我尝试在浏览器中提交表单时,控制台会向我显示 400 个错误的请求。该功能适用于后端并返回 200 ok 状态,但不适用于前端。
this is a picture of the error in the browser.
下面是我的代码
验证
const Validator = require("validator");
const isEmpty = require("is-empty");
module.exports = function validateRegisterInput(data) {
let errors = {};
data.name = !isEmpty(data.name) ? data.name : "";
data.email = !isEmpty(data.email) ? data.email: "";
data.password = !isEmpty(data.password) ? data.password: "";
data.password2 = !isEmpty(data.password2) ? data.password2: "";
if(Validator.isEmpty(data.name)) {
errors.name = "Name field is required";
}
if(Validator.isEmpty(data.email)) {
errors.email = "Email field is required";
} else if(!Validator.isEmail(data.email)) {
errors.email = "Email is invalid"
}
if (Validator.isEmpty(data.password)) {
errors.password = "Password field is required";
}
if (Validator.isEmpty(data.password2)) {
errors.password2 = "Confirm password field is required";
}
if(!Validator.isLength(data.password,{min: 6,max: 30})){
errors: password = "Password must be at least 6 characters";
}
if(!Validator.equals(data.password,data.password2)){
errors.password2 = "Password must match"
}
return {
errors,isValid: isEmpty(errors)
};
};
控制器
const express = require("express");
const router = express.Router();
const bcrypt = require("bcryptjs");
const jwt = require ("jsonwebtoken");
const keys = require("../../config/key");
const validateRegisterInput = require("../../validation/register");
const validateLoginInput = require("../../validation/login");
const User = require("../../models/User");
router.post("/register",(req,res) => {
//FORM VALIDATION
const {errors,isValid } = validateRegisterInput(req.body)
//CHECK VALIDATION
if(!isValid) {
return res.status(400).json(errors)
}
User.findOne({ email: req.body.email }).then( returnedUser => {
if(returnedUser) {
return res.status(400).json({email: "Email already exists"});
}
});
// saving user with request information to database
const newUser = new User({
name: req.body.name,email: req.body.email,password: req.body.password,});
bcrypt.genSalt(10,(err,salt)=>{
bcrypt.hash(newUser.password,salt,hash)=>{
if(err) throw err;
newUser.password = hash;
newUser
.save()
.then(user => res.json(user))
.catch(err => console.log(err));
});
});
});
router.post("/login",res)=>{
const {errors,isValid} = validateLoginInput(req.body)
if(!isValid){
return res.status(400).json(errors)
}
const email = req.body.email;
const password = req.body.password
User.findOne({ email: email }).then(user =>{
if(!user){
return res.status(404).json({ emailNotFound: "Email not found"});
}
bcrypt.compare(password,user.password).then(isMatch => {
if(isMatch){
const payload = { id: user.id,name: user.name };
jwt.sign(payload,keys.secretorKey,{expiresIn: 31556926},token) => {
res.json({ success: true,token: "Bearer " + token });
});
} else {
return res.status(400)
.json({passwordincorrect: "password incorrect"})
}
})
})
});
module.exports = router;
动作
import axios from "axios";
import setAuthToken from "../utils/setAuthToken";
import jwt_decode from "jwt-decode";
import {
GET_ERRORS,SET_CURRENT_USER,USER_LOADING
} from "./types";
// Register User
export const registerUser = (userData,history) => dispatch => {
axios.post("/api/users/register",userData)
.then(res => history.push("/login")) // re-direct to login on successful register
.catch(err =>
dispatch({
type: GET_ERRORS,payload: err.response.data
})
);
};
// Login - get user token
export const loginUser = userData => dispatch => {
axios
.post("/api/users/login",userData)
.then(res => {
// Save to localStorage
// Set token to localStorage
const { token } = res.data;
localStorage.setItem("jwtToken",token);
// Set token to Auth header
setAuthToken(token);
// Decode token to get user data
const decoded = jwt_decode(token);
// Set current user
dispatch(setCurrentUser(decoded));
})
.catch(err =>
dispatch({
type: GET_ERRORS,payload: err.response.data
})
);
};
// Set logged in user
export const setCurrentUser = decoded => {
return {
type: SET_CURRENT_USER,payload: decoded
};
};
// User loading
export const setUserLoading = () => {
return {
type: USER_LOADING
};
};
// Log user out
export const logoutUser = () => dispatch => {
// Remove token from local storage
localStorage.removeItem("jwtToken");
// Remove auth header for future requests
setAuthToken(false);
// Set current user to empty object {} which will set isAuthenticated to false
dispatch(setCurrentUser({}));
};
组件
import React,{ Component } from "react";
import { Link,withRouter } from "react-router-dom";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { registerUser } from "../../actions/authActions";
import classnames from "classnames";
class Register extends Component {
constructor() {
super();
this.state = {
name: "",email: "",password: "",password2: "",errors: {},};
}
componentDidMount() {
// If logged in and user navigates to Register page,should redirect them to dashboard
if (this.props.auth.isAuthenticated) {
this.props.history.push("/dashboard");
}
}
componentwillReceiveProps(nextProps) {
if (nextProps.errors) {
this.setState({
errors: nextProps.errors,});
}
}
onChange = (e) => {
this.setState({ [e.target.id]: e.target.value });
};
onSubmit = (e) => {
e.preventDefault();
const newUser = {
name: this.state.name,email: this.state.email,password: this.state.password,password2: this.state.password2,};
console.log(newUser);
this.props.registerUser(newUser,this.props.history);
};
render() {
const { errors } = this.state;
return (
<div className="container">
<div className="row">
<div className="col s8 offset-s2">
<Link to="/" className="btn-flat waves-effect">
<i className="material-icons left">keyboard_backspace</i> Back to
home
</Link>
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<h4>
<b>Register</b> below
</h4>
<p className="grey-text text-darken-1">
Already have an account? <Link to="/login">Log in</Link>
</p>
</div>
<form novalidate onSubmit={this.onSubmit}>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.name}
error={errors.name}
id="name"
type="text"
className={classnames("",{
invalid: errors.name
})}
/>
<label htmlFor="name">Name</label>
<span className="red-text">{errors.name}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.email}
error={errors.email}
id="email"
type="email"
className={classnames("",{
invalid: errors.email
})}
/>
<label htmlFor="email">Email</label>
<span className="red-text">{errors.email}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.password}
error={errors.password}
id="password"
type="password"
className={classnames("",{
invalid: errors.password
})}
/>
<label htmlFor="password">Password</label>
<span className="red-text">{errors.password}</span>
</div>
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.password2}
error={errors.password2}
id="password2"
type="password"
className={classnames("",{
invalid: errors.password2
})}
/>
<label htmlFor="password2">Confirm Password</label>
<span className="red-text">{errors.password2}</span>
</div>
<div className="col s12" style={{ paddingLeft: "11.250px" }}>
<button
style={{
width: "150px",borderRadius: "3px",letterSpacing: "1.5px",marginTop: "1rem",}}
type="submit"
className="btn btn-large waves-effect waves-light hoverable blue accent-3"
>
Sign up
</button>
</div>
</form>
</div>
</div>
</div>
);
}
}
Register.propTypes = {
registerUser: PropTypes.func.isrequired,auth: PropTypes.object.isrequired,errors: PropTypes.object.isrequired,};
const mapStatetoProps = (state) => ({
auth: state.auth,errors: state.errors,});
export default connect(mapStatetoProps,{ registerUser })(withRouter(Register));
这里是根服务器
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const passport = require("passport");
const app = express();
const users = require("./controllers/api/users")
app.use(
bodyParser.urlencoded({
extended: false
})
);
//DATA BASE CONfigURATION
const dbkeys = require("./config/key").mongoURI;
mongoose.connect(
dbkeys,{useNewUrlParser: true} )
.then(()=> console.log("database connection successful"))
.catch(err => console.log(err))
app.use(passport.initialize());
require("./config/passport")(passport);
app.use("/api/users",users);
const port = 5000;
app.listen( port,() => console.log("server us up and running on port 5000!"))
解决方法
Axios 将数据作为 JSON (sort_dependencies' 7: from /Users/Antonio/.rvm/rubies/ruby-2.6.1/lib/ruby/site_ruby/2.6.0/rubygems/resolver/molinillo/lib/molinillo/delegates/specification_provider.rb:69:in
) 发送。您目前仅使用 block in sort_dependencies' 5: from /Users/Antonio/.rvm/rubies/ruby-2.6.1/lib/ruby/site_ruby/2.6.0/rubygems/resolver.rb:279:in
的正文解析器,它指的是 with_index' 3: from /Users/Antonio/.rvm/rubies/ruby-2.6.1/lib/ruby/site_ruby/2.6.0/rubygems/resolver.rb:279:in
,这是 each' 1: from /Users/Antonio/.rvm/rubies/ruby-2.6.1/lib/ruby/site_ruby/2.6.0/rubygems/resolver.rb:285:in
默认使用的数据格式。
您还需要使用 application/json
:
urlencoded
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。