Я довольно новичок в стеке MERN. Я пытаюсь настроить аутентификацию пользователя с помощью jwt.
Проблема возникает только тогда, когда я использую интерфейс для входа в систему. Когда я использую POST man для выполнения http-запроса, вход в систему успешен
Однако, когда я вхожу, используя электронную почту и пароль, я получаю следующую ошибку:
Консоль
Uncaught (in promise) TypeError: Cannot read property 'data' of undefined
at authActions.js:40
Я знаю, что это показывает, где находится ошибка, но я все еще не могу ее исправить.
authActions.js
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({}));
};
Ниже приведен мой код для входа в систему.
login.jsx
class Login extends Component {
constructor(props) {
super(props);
this.state = {
email: "",
password: ""
};
}
componentDidMount() {
// If logged in and user navigates to Login page, should redirect them to dashboard
if (this.props.auth.isAuthenticated) {
this.props.history.push("/dashboard");
}
}
validateForm() {
return this.state.email.length > 0 && this.state.password.length > 0;
}
componentWillReceiveProps(nextProps) {
if (nextProps.auth.isAuthenticated) {
this.props.history.push("/dashboard"); // push user to dashboard when they login
}
if (nextProps.errors) {
this.setState({
errors: nextProps.errors
});
}
}
handleChange = event => {
this.setState({
[event.target.id]: event.target.value
});
};
handleSubmit = event => {
event.preventDefault();
console.log("Submit called");
const userData = {
email: this.state.email,
password: this.state.password
};
this.props.loginUser(userData);
};
render() {
const errors = this.state;
return (
<div className="Login">
<form onSubmit={this.handleSubmit}>
<FormGroup controlId="email" bs="large">
<FormLabel>Email</FormLabel>
<span className="red-text">{errors.emailnotfound}</span>
<FormControl
autoFocus
type="email"
value={this.state.email}
onChange={this.handleChange}
className={classnames("", {
invalid: errors.email || errors.emailnotfound
})}
/>
</FormGroup>
<FormGroup controlId="password" bs="large">
<FormLabel>Password</FormLabel>
<span className="red-text">
{errors.password}
{errors.passwordincorrect}
</span>
<FormControl
value={this.state.password}
onChange={this.handleChange}
type="password"
className={classnames("", {
invalid: errors.password || errors.passwordincorrect
})}
/>
</FormGroup>
<Button
block
bs="large"
disabled={!this.validateForm()}
type="submit"
>
Login
</Button>
<br />
<p> Dont have account ? </p>
<Link to="/register">
{" "}
<p style={{ color: "blue" }}> Join Us </p>{" "}
</Link>
</form>
<br />
</div>
);
}
}
Я упустил некоторые операторы импорта, чтобы сократить код.