Я хочу изменить пароль пользователя с помощью запроса (или публикации). У меня есть три (или даже четыре) файла:
src / actions / authActions. js
src / redurs / authReducer. js
маршруты / API / пользователи. js
- маршруты / API / Auth. js
Вот authActions. js и authReducer:
authActions. js
import axios from 'axios';
import { returnErrors } from './errorActions';
// import { tokenConfig } from './authActions';
import {
USER_LOADED,
USER_LOADING,
AUTH_ERROR,
LOGIN_SUCCESS,
LOGIN_FAIL,
LOGOUT_SUCCESS,
REGISTER_SUCCESS,
REGISTER_FAIL,
CHANGE_PASSWORD
} from './types';
// Check token & load user
export const loadUser = () => (dispatch, getState) => {
// User loading
dispatch({ type: USER_LOADING });
axios.get('/api/auth/user', tokenConfig(getState))
.then(res => dispatch({
type: USER_LOADED,
payload: res.data
}))
.catch(err => {
dispatch(returnErrors(err.response.data, err.response.status));
dispatch({
type: AUTH_ERROR
});
});
};
// Register User
export const register = ({ name, email, password }) => dispatch => {
// Headers
const config = {
headers: {
'Content-Type': 'application/json'
}
}
// Request body
const body = JSON.stringify({ name, email, password })
axios.post('/api/users', body, config)
.then(res => dispatch({
type: REGISTER_SUCCESS,
payload: res.data
}))
.catch(err => {
dispatch(returnErrors(err.response.data, err.response.status, 'REGISTER_FAIL'));
dispatch({
type: REGISTER_FAIL
});
});
}
// Register User
export const changePassword = (id, password) => (dispatch, getState) => {
// Headers
const config = {
headers: {
'Content-Type': 'application/json'
}
}
// Request body
const body = JSON.stringify(password);
axios.put(`/api/auth/user/${id}`, password, tokenConfig(getState))
.then(res => dispatch({
type: CHANGE_PASSWORD,
payload: res.data
}))
.catch(err =>
dispatch(returnErrors(err.response.data, err.response.status))
);
}
// Login User
export const login = ({ email, password }) => dispatch => {
// Headers
const config = {
headers: {
'Content-Type': 'application/json'
}
}
// Request body
const body = JSON.stringify({ email, password })
axios.post('/api/auth', body, config)
.then(res => dispatch({
type: LOGIN_SUCCESS,
payload: res.data
}))
.catch(err => {
dispatch(returnErrors(err.response.data, err.response.status, 'LOGIN_FAIL'));
dispatch({
type: LOGIN_FAIL
});
});
}
// Logout User
export const logout = () => {
return {
type: LOGOUT_SUCCESS
};
};
// Setup config/headers and token
export const tokenConfig = getState => {
// Get token from localstorage
const token = getState().auth.token;
// Headers
const config = {
headers: {
// "Accept": "application/json, multipart/form-data"
"Content-type": "application/json"
}
}
// If token, add to headers
if (token) {
config.headers['x-auth-token'] = token;
}
return config;
}
и authReducer. js
import {
USER_LOADED,
USER_LOADING,
AUTH_ERROR,
LOGIN_SUCCESS,
LOGIN_FAIL,
LOGOUT_SUCCESS,
REGISTER_SUCCESS,
REGISTER_FAIL,
CHANGE_PASSWORD
} from '../actions/types';
const initialState = {
token: localStorage.getItem('token'),
isAuthenticated: false,
user: null
};
export default function (state = initialState, action) {
switch (action.type) {
case USER_LOADING:
return {
...state,
isLoading: true
};
case USER_LOADED:
return {
...state,
isAuthenticated: true,
isLoading: false,
user: action.payload
};
case CHANGE_PASSWORD:
return {
...state,
user: state.user.map(
user =>
user._id === action.payload.id
//return action payload (modified user) instead of
// original user when user id is updated
? action.payload
: user//ids not the same, return original user
)
};
case LOGIN_SUCCESS:
case REGISTER_SUCCESS:
localStorage.setItem('token', action.payload.token);
return {
...state,
...action.payload,
isAuthenticated: true,
isLoading: false
};
case AUTH_ERROR:
case LOGIN_FAIL:
case LOGOUT_SUCCESS:
case REGISTER_FAIL:
localStorage.removeItem('token');
return {
...state,
token: null,
user: null,
isAuthenticated: false,
isLoading: false
};
default:
return state;
}
}
Есть также маршруты / API , но ни одно из отправленных мной сообщений даже не достигает их.
Все проблемы касаются CHANGE_PASSWORD
case (редукторов) и помещают запросы в authActions
и маршруты / файлы api. Вот также оба файла route / api (я сделал два путевых маршрута, чтобы проверить, достигает ли он хотя бы одного из них, но ни один из них не работает и даже если он работает, но не так, как я ожидал, у меня все еще есть доступ к моей базе данных, чтобы я мог исправить это напрямую):
маршруты / API / пользователи. js (используется для регистрации)
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const config = require('config');
const jwt = require('jsonwebtoken');
// Item Model
const User = require('../../models/User');
// @route POST api/users
// @desc Register new user
// @access Public
router.post('/', (req, res) => {
const { name, email, password } = req.body;
// Simple validation
if (!name || !email || !password) {
return res.status(400).json({ msg: 'Please enter all fields' });
}
// Check for existing user
User.findOne({ email })
.then(user => {
if (user) return res.status(400).json({ msg: 'User already exists' });
const newUser = new User({
name,
email,
password
});
// Create salt & hash
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
if (err) throw err;
newUser.password = hash;
newUser.save()
.then(user => {
jwt.sign(
{ id: user.id },
config.get('jwtSecret'),
{ expiresIn: 3600 },
(err, token) => {
if (err) throw err;
res.json({
token,
user: {
id: user.id,
name: user.name,
email: user.email
}
});
}
)
});
})
})
})
});
router.put('/:id', (req, res) => {
const { password } = req.body;
console.log(req.params);
// Simple validation
if (!password) {
return res.status(400).json({ msg: 'Please enter all fields' });
}
// // Check for existing user
User.findOne({ _id: req.params.id })
.then(user => {
const secret = user.password
const payload = jwt.decode(token, secret)
if (payload.id === user.id) {
bcrypt.genSalt(10, function (err, salt) {
// Call error-handling middleware:
if (err) return
bcrypt.hash(password, salt, function (err, hash) {
// Call error-handling middleware:
if (err) return
User.findOneAndUpdate({ _id: req.params.id }, { password: hash })
.then(() => res.status(202).json("Password changed accepted"))
.catch(err => res.status(500).json(err))
})
})
}
})
.catch(() => {
res.status(404).json("Invalid user")
})
});
module.exports = router;
маршруты / API / Auth. js (используется для проверки подлинности)
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const config = require('config');
const jwt = require('jsonwebtoken');
const auth = require('../../middleware/auth')
// Item Model
const User = require('../../models/User');
// @route POST api/auth
// @desc Auth user
// @access Public
router.post('/', (req, res) => {
const { email, password } = req.body;
// Simple validation
if (!email || !password) {
return res.status(400).json({ msg: 'Please enter all fields' });
}
// Check for existing user
User.findOne({ email })
.then(user => {
if (!user) return res.status(400).json({ msg: 'User does not exist' });
// Validate password
bcrypt.compare(password, user.password)
.then(isMatch => {
if (!isMatch) return res.status(400).json({ msg: 'Invalid credentials' });
jwt.sign(
{ id: user.id },
config.get('jwtSecret'),
{ expiresIn: 3600 },
(err, token) => {
if (err) throw err;
res.json({
token,
user: {
id: user.id,
name: user.name,
email: user.email
}
});
}
)
})
})
});
router.put('/user/:id', auth, (req, res) => {
const { password } = req.body;
console.log(req.params);
// Simple validation
if (!password) {
return res.status(400).json({ msg: 'Please enter all fields' });
}
// // Check for existing user
User.findOne({ _id: req.params.id })
.then(user => {
const secret = user.password
const payload = jwt.decode(token, secret)
if (payload.id === user.id) {
bcrypt.genSalt(10, function (err, salt) {
// Call error-handling middleware:
if (err) return
bcrypt.hash(password, salt, function (err, hash) {
// Call error-handling middleware:
if (err) return
User.findOneAndUpdate({ _id: req.params.id }, { password: hash })
.then(() => res.status(202).json("Password changed accepted"))
.catch(err => res.status(500).json(err))
})
})
}
})
.catch(() => {
res.status(404).json("Invalid user")
})
});
// @route GET api/auth/user
// @desc Get user data
// @access Private
router.get('/user', auth, (req, res) => {
User.findById(req.user.id)
.select('-password')
.then(user => res.json(user));
});
module.exports = router;
Я знаю, что это много кода, но, возможно, я что-то упустил. Таким образом, все вещи, кроме этих маршрутов PUT