Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forbidden (403) in a post request - djangorest-react

I have an endpoint for users registration. I use react for my front side of project. I send POST request to the endpoint with json body to register user. but it return's Forbidden (403). When I use postman to test functionality everything is Ok but with axios It is not.

Error: POST /user/register/ 403 (Forbidden)

endpoint: user/register/

Register API View:

class UserRegisterAPIView(APIView):
    serializer_class = UserRegisterSerializer
    permission_classes = [permissions.AllowAny]

    def post(self, request, format=None, *args, **kwargs):
        print(request.data)
        serializer = UserRegisterSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.save()
        user_data = serializer.validated_data
        return Response(user_data)

Register Serializer: I used django's default model User

from django.contrib.auth.models import User
class UserRegisterSerializer(serializers.ModelSerializer):
    password2   = serializers.CharField(
        style={'input_type': 'password'})

    class Meta:
        model = User
        fields = ["username", "email", "password", "password2"]
        extra_kwargs = {
        'password': {'write_only': True},
        'password2': {'write_only': True}
        }

    def validate(self, data):
        password    = data.get('password')
        password2   = data.pop('password2')

        if len(str(password)) < 5:
            raise serializers.ValidationError("Password is too short.")
        if password != password2:
            raise serializers.ValidationError("Passwords don't match.")
        return data

    def create(self, validated_data):
        username = validated_data.get('username')
        email    = validated_data.get('email')
        password = validated_data.get('password')

        user = User.objects.create_user(username=username, email=email,
                password=password)

        if user and user.is_active:
            return user

Register Component: I've imported action register.

Note: I deleted other input fields to decrease code

export class Register extends Component {

  state = {
    username: '',
    password: '',
    password2: '',
    email: '',
  }

  onChange = (e) => this.setState({ [e.target.name]: e.target.value })

  onSubmit = (e) => {
    e.preventDefault();
    this.props.register(this.state)
  }

  render() {
    return (
      <div className="col-md-6 m-auto">
        <div className="card card-body mt-5">
          <form onSubmit={this.onSubmit}>
            <div className="form-group">
              <label>Username</label>
              <input
                type="text"
                className="form-control"
                name="username"
                onChange={this.onChange}
              />
            </div>
            <div className="form-group">
              <button type="submit" className="btn btn-primary">
                Register
              </button>
            </div>
            <p>
              Already have an account? <Link to="/login">Login</Link>
            </p>
          </form>
        </div>
      </div>
    )
  }
}


export default connect(null, { register })(Register);

Action:

export const register = ({
  username,
  password,
  password2,
  email
}) => dispatch => {
  const config = {
    headers: {
      'Content-Type': 'application/json',
    }
  }
  const body = JSON.stringify({
    username,
    password,
    password2,
    email
  });

  axios.post('/user/register/', body, config)
    .then(res => {
      dispatch({
        type: REGISTER_SUCCESS,
        payload: res.data
      })
    }).catch(err => {
      dispatch({
        type: REGISTER_FAIL,
        payload: err
      })
      console.log(err)
    })
}

Reducer:

import { REGISTER_SUCCESS, REGISTER_FAIL } from './../actions/types';

const initialState = {
  user: null,
  error: null,
}

export default function (state = initialState, action) {
  switch (action.type) {
    case REGISTER_SUCCESS:
      console.log("Register success")
      return {
        ...state,
        user: action.payload,
      }
    case REGISTER_FAIL:
      return {
        ...state,
        user: null,
        error: action.payload
      }
    default: {
      return state;
    }
  }
}
like image 999
The Mir Avatar asked Dec 21 '25 21:12

The Mir


1 Answers

Seems that you are not passing CSRF in your header:

Try to put it in your header:

'X-CSRFToken': csrftoken

The value if CSRF token you can get from cookies. For more info about CSRF you can refer to Django 3.2 official docs.

like image 126
Sergey Pugach Avatar answered Dec 23 '25 11:12

Sergey Pugach



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!