I have been working on authentication with my project. I have a REST api backend that serves JWT tokens. My front end stack is ReactJS, Redux, Axios and Redux Thunk.
My question is why when I submit my form it does not send any credentials?
But when I console log the action and payload on credChange it seems to be correct. Am I not setting the state somewhere? Also, axios does not catch the 400 Bad Request error.
Here is my code:
AuthActions.js
export const credChange = ({ prop, value }) => {
return {
type: CRED_CHANGE,
payload: { prop, value },
};
};
export const logoutUser = () => {
return (dispatch) => {
dispatch({ type: LOGOUT_USER });
};
};
const loginSuccess = (dispatch, response) => {
dispatch({
type: LOGIN_USER_SUCCESS,
payload: response.data.token,
});
};
const loginError = (dispatch, error) => {
dispatch({
type: LOGIN_USER_ERROR,
payload: error.response.data,
});
};
export const loginUser = ({ empNum, password }) => {
return (dispatch) => {
dispatch({ type: LOGIN_USER });
axios({
method: 'post',
url: 'http://127.0.0.1:8000/profiles_api/jwt/authTK/',
data: {
emp_number: empNum,
password,
},
})
.then(response => loginSuccess(dispatch, response))
.catch(error => loginError(dispatch, error));
};
};
AuthReducer.js
const INITIAL_STATE = {
empNum: '',
password: '',
empNumErr: null,
passwordErr: null,
authTK: null,
loading: false,
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case CRED_CHANGE:
return { ...state, [action.payload.prop]: action.payload.value };
case LOGIN_USER:
return {
...state,
...INITIAL_STATE,
loading: true,
};
case LOGOUT_USER:
return {
...state,
INITIAL_STATE,
};
case LOGIN_USER_SUCCESS:
return {
...state,
...INITIAL_STATE,
authTK: action.payload,
};
case LOGIN_USER_ERROR:
return {
...state,
...INITIAL_STATE,
empNumErr: action.payload.emp_number,
passwordErr: action.payload.password,
};
default:
return state;
}
};
LoginForm.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import {
credChange,
loginUser,
logoutUser,
} from '../Actions';
class LoginForm extends Component {
constructor() {
super();
this.onFormSubmit = this.onFormSubmit.bind(this);
this.renderEmpNumErr = this.renderEmpNumErr.bind(this);
this.empNumChange = this.empNumChange.bind(this);
this.passwordChange = this.passwordChange.bind(this);
}
onFormSubmit() {
const { empNum, password } = this.props;
this.props.loginUser({ empNum, password });
}
empNumChange(text) {
this.props.credChange({ prop: 'empNum', value: text.target.value });
}
passwordChange(text) {
this.props.credChange({ prop: 'password', value: text.target.value });
}
renderEmpNumErr() {
if (this.props.empNumErr) {
return (
<p>
{this.props.empNumErr}
</p>
);
}
return null;
}
render() {
return (
<div>
<form onSubmit={this.onFormSubmit}>
<label htmlFor="numberLabel">Employee Number</label>
<input
id="numberLabel"
type="password"
value={this.props.empNum}
onChange={this.empNumChange}
/>
<label htmlFor="passLabel">Password</label>
<input
id="passLabel"
type="password"
value={this.props.password}
onChange={this.passwordChange}
/>
<button type="submit">Login</button>
</form>
{this.renderEmpNumErr()}
</div>
);
}
}
const mapStateToProps = ({ counter }) => {
const {
empNum,
password,
loading,
empNumErr,
passwordErr,
authTK,
} = counter;
return {
empNum,
password,
loading,
empNumErr,
passwordErr,
authTK,
};
};
export default connect(mapStateToProps, { credChange, loginUser, logoutUser })(LoginForm);
After Submitting form with credentials
The console says:
POST XHR http://127.0.0.1:8000/profiles_api/jwt/authTK/ [HTTP/1.0 400 Bad Request 5ms]
And the POST request Raw Data is blank, therefore no credentials were sent.
{"emp_number":["This field is required."],"password":["This field is required."]}
EDIT If there is any other information I can provide please say so but I think this should be sufficient.