【发布时间】:2021-05-11 01:22:03
【问题描述】:
尝试设置会弹出错误的身份验证,该错误会根据尝试注册时出现的错误而变化。无法弄清楚为什么我会收到此错误。任何帮助将不胜感激
我附上了一张错误图片和代码,以帮助弄清楚发生了什么。当密码不匹配时,我可以弹出警报,但对于没有姓名、没有电子邮件和没有密码的其他错误,我无法让它工作
动作
import axios from 'axios'
import { setAlert } from './alert'
import { REGISTER_SUCCESS, REGISTER_FAIL } from './types'
export const register = ({ name, email, password }) => async dispatch => {
const config = {
headers: { 'Content-Type': 'application/json' }
}
const body = JSON.stringify({ name, email, password })
try {
const res = await axios.post('/api/users', body, config)
dispatch({
type: REGISTER_SUCCESS,
payload: res.data
})
} catch (err) {
const errors = err.response.data.errors
if (errors) {
errors.forEach(error => dispatch(setAlert(error.msg, 'danger')))
}
dispatch({
type: REGISTER_FAIL
})
}
}
提醒
// bring in set types
import { SET_ALERT, REMOVE_ALERT } from '../actions/types'
// set initial state as empty
const initialState = []
// export fucntion that takes in that that is initial state and an action
export default function something (state = initialState, action) {
// destructure action
const { type, payload } = action
// evaluate actions based on their type
switch (type) {
// in case of set alert
case SET_ALERT:
// copy into array, alert that is given to us in state, and set alert with action.payload
return [...state, payload]
case REMOVE_ALERT:
// use filter to find a specific alert and see if alert id is NOT equal to the alert in the payload (filter through all alerts except the one that matches the payload)
return state.filter(alert => alert.id !== payload)
// default to simply returning the state
default:
return state
}
}
注册
import React, { Fragment, useState } from 'react'
// bring in connect
import { connect } from 'react-redux'
// bring in setAlert
import { setAlert } from '../../actions/alert'
import { register } from '../../actions/auth'
// bring in proptypes
import PropTypes from 'prop-types'
const Register = ({ setAlert, register }) => {
// the object full of values is formData, function to update state(formData) is setform data
const [ formData, setFormData ] = useState({
// default state values
name: '',
email: '',
password: '',
password2: ''
})
// destructure formData
const { name, email, password, password2 } = formData
// the on chage at the level of the individual form input will call the onChange function that will call setFormData which
// changes the value based on the name of the target and the value inputed to the target
const onChange = e => setFormData({ ...formData, [e.target.name]: e.target.value })
// on submit funciton arrow function
const onSubmit = e => {
// prevent lock
e.preventDefault()
// if password does not match password too, log error message the alert is the class for the styling
if (password !== password2) {
setAlert('passwords do not match', 'danger')
// if it does work, log the data in the state
} else {
register({ name, email, password })
}
}
// adding value={variable} asociates the variable with the current state, the on change causes the state to be updated
return (
<Fragment>
<h1> Registration </h1>
<p> Create your account </p>
<form onSubmit={e => onSubmit(e)}>
<div>
<input
type='text'
placeholder='Name'
name='name'
value={name}
onChange={e => onChange(e)}
/>
</div>
<div>
<input
type='email'
placeholder='Email Address'
name='email'
value={email}
onChange={e => onChange(e)}
/>
</div>
<div>
<input
type='password'
placeholder='Password'
name='password'
minLength='6'
value={password}
onChange={e => onChange(e)}
/>
</div>
<div>
<input
type='password'
placeholder='Confirm Password'
name='password2'
minLength='6'
value={password2}
onChange={e => onChange(e)}
/>
</div>
<div>
<input type='submit' value='Register' />
</div>
<p>
Already have an account?
<a href='/login' > Login </a>
</p>
</form>
</Fragment>
)
}
// proptype regis
Register.propTypes = {
setAlert: PropTypes.func.isRequired,
register: PropTypes.func.isRequired
}
// export using connect the null is temporar and this lets us pass setAlert (actions we want to use from props) State, object with actions we want to use
export default connect(null, { setAlert, register })(Register)
身份验证 API
// bring in express
const express = require('express')
// bring in router
const router = express.Router()
// Bring in middleware
const auth = require('../../middleware/auth')
// bring in user model
const User = require('../../models/Users')
// bring in validator
const { check, validationResult } = require('express-validator')
// Bring in JWT
const jwt = require('jsonwebtoken')
// Bring in secret
const config = require('config')
// Bring in Bcrypt
const bcrypt = require('bcryptjs')
// @Route: Get api/auth
// @Description: Test route
// @access: Public
// when using path api/auth/ send "auth route" response *add auth to make the route protected by middleware* make it asynch
router.get('/', auth, async (req, res) => {
// when accessing this get request
try {
// search user model by id and excldue the password
const user = await User.findById(req.user.id).select('-password')
// respond with the information taken from the database tied to the selected id
res.json(user)
// if unable to find by id
} catch (err) {
// log error
console.error(err.message)
// send error code 500 and server error dialogue
res.status(500).send('server error')
}
})
// @Route: Post api/auth
// @Description: Authenticate user and get token
// @access: Public
// get api/users/ will send response of user route
router.post(
'/',
// adds secondary requirement of running checks
[
// check email is valid
check('email', 'Please Include Valid Email').isEmail(),
// check email is present
check('password', 'Password is requried').exists()
],
// asynch because is its what is commonly used
async (req, res) => {
// set errors to result from validation
const errors = validationResult(req)
// if not errors is empty
if (!errors.isEmpty()) {
// reutn the status 400 and an json array that shows the error.
return res.status(400).json({ errors: errors.array() })
}
// bring in user information, destructure req.body into email, and password for ease of use
const { email, password } = req.body
try {
// check if user exists
// look at response to find email
let user = await User.findOne({ email })
// if user is not found
if (!user) {
// send error status and show invalid crednetials
return res.status(400).json({ errors: [{ msg: 'Invalid Credentials' }] })
}
// check that password matches to the user by comparing the plain text password to the encrypted password
const isMatch = await bcrypt.compare(password, user.password)
// if it does not match then throw 400 status and show invalid credential message
if (!isMatch) {
// 400 response and jsonformat response of invalid credentials
return res.status(400).json({ errors: [{ Msg: 'Invalid crednetials ' }] })
}
// return jsonwebtoken
// create payload to use with jwt
const payload = {
// look at saved user
user: {
// pull out promised user.id
id: user.id
}
}
// jwt sign
// sign with payload and with jwttoken pulled from default.json
jwt.sign(
payload,
// configures the jwt token
config.get('jwtSecret'),
// expires in an hour
{ expiresIn: 3600 },
// if an error
(err, token) => {
// throw the error
if (err) throw err
// response with the token
res.send({ token })
// console.log(token)
}
)
} catch (err) {
// console the error message
console.error(err.message)
// send 500 status with server error text
res.status(500).send('server error')
}
console.log('something was posted')
})
// export route to be used in other parts of the program
module.exports = router
用户路线
// brining in express
const express = require('express')
// bring in router
const router = express.Router()
// bring in validator
const { check, validationResult } = require('express-validator')
// bring in user model
const User = require('../../models/Users')
// Bring in Bcrypt
const bcrypt = require('bcryptjs')
// Bring in JWT
const jwt = require('jsonwebtoken')
// Bring in secret
const config = require('config')
// @Route: Get api/users
// @Description: Test route
// @access: Public
// get api/users/ will send response of user route
// router.get('/', (req, res) => res.send('User Route'))
// @Route: Post api/users
// @Description: Register User
// @access: Public
// get api/users/ will send response of user route
router.post('/',
// adds secondary requirement of running checks
[
console.log('fart'),
// check to make sure a name is present (that its not empty)
check('name', 'Name is required')
.not()
.isEmpty(),
// check email is valid
check('email', 'Please Include Valid Email').isEmail(),
// check email has min 6 char
check('password', 'Please enter a password with 6 Character minimum').isLength({ min: 6 })
],
// asynch because is its what is commonly used
async (req, res) => {
// set errors to result from validation
const errors = validationResult(req)
// if not errors is empty
if (!errors.isEmpty()) {
// reutn the status 400 and an json array that shows the error.
return res.status(400).json({ errors: errors.array() })
}
// bring in user information, destructure req.body into name, email, and password for ease of use
const { name, email, password } = req.body
try {
// check if user exists
// look at response to find email
let user = await User.findOne({ email })
// if user already exists
if (user) {
// send error status and show user already exists message on client
return res.status(400).json({ errors: [{ msg: 'user already exists' }] })
}
// creates new user
user = new User({
name,
email,
password
})
// encrypt password
// generates salt from bycrpt promise
const salt = await bcrypt.genSalt(10)
// hashes password from newly created user and sets it to user.password
user.password = await bcrypt.hash(password, salt)
// save user use await since it leaves a promise
await user.save()
// return jsonwebtoken
// create payload to use with jwt
const payload = {
// look at saved user
user: {
// pull out promised user.id
id: user.id
}
}
// jwt sign
// sign with payload and with jwttoken pulled from default.json
jwt.sign(
payload,
// configures the jwt token
config.get('jwtSecret'),
// expires in an hour
{ expiresIn: 3600 },
// if an error
(err, token) => {
// throw the error
if (err) throw err
// response with the token
res.send({ token })
// console.log(token)
}
)
} catch (err) {
// console the error message
console.error(err.message)
// send 500 status with server error text
res.status(500).send('server error')
}
console.log('something was posted')
})
// exporting the route to be used in other parts of the program
module.exports = router
服务器
/* requre express */
const express = require('express')
// require the connectDB function from db.js
const connectDB = require('./config/db')
/* create app that uses express */
const app = express()
// Connect Database
connectDB()
// initialize middleware
app.use(express.json({ extended: false }))
/* Default to port 5000 */
const PORT = process.env.PORT || 5000
/* Check to make sure API is running */
app.get('/', (req, res) => res.send('API is Running'))
// Define routes
// make /api/users pertain to the user.js file so that we can use any routes that start with "/"
// when using /api/users we are really using './routes/api/users'
app.use('/api/users', require('./routes/api/users'))
// make /api/users pertain to the user.js file so that we can use any routes that start with "/"
// when using /api/users we are really using './routes/api/users'
app.use('/api/auth', require('./routes/api/auth'))
/* Listen for Server starting and output the port it started on */
app.listen(PORT, () => console.log(`server started on port ${PORT}`))
【问题讨论】:
-
您的 api 服务器是否在 3000 端口上运行?我认为它不是,因为这是反应开发服务器运行的地方。
-
我的 api 在端口 5000 上运行,我不确定如何将请求从端口 3000 更改为端口 5000
-
axios.post('http://localhost:5000/api/users'
标签: javascript http-status-code-404 mern