'flask jwt extended with status code 401 in React frontend

I am using Flask-JWT-Extended, and Flask CORS with React to make a web app. According to the documents of Flask-JWT-Extended which provide the "Protected" route to check the JWT token. I can use Axios get to get the protected route successfully but can't succeed in Axios post request ( The post request can be sent through Postman successfully).

I have two questions.

  1. How can I succeed to post a request to the Flask backend from React. When I used Postman, the post request is okay but it's not okay in React (Request failed with status code 401) and (Missing JWT in headers, cookies, json or query_str…key in json data)

(Solved, just the headers position in wrong a place)

  1. Since the token sent to frontend by Flask is an HTTP-only cookie. How does Axios send the post header with "access_token_cookie"

Flask- app.py

from textwrap import indent
from flask import Flask, request, jsonify, redirect, Response
import pymongo
from pymongo import MongoClient
from pymongo import ReturnDocument

import json
# MongoDB use bson
from bson import json_util
from bson.json_util import dumps, loads
# Flask JWT Extended
from flask_jwt_extended import create_access_token
from flask_jwt_extended import jwt_required
from flask_jwt_extended import JWTManager
from flask_jwt_extended import set_access_cookies
from flask_jwt_extended import set_refresh_cookies
from flask_jwt_extended import unset_jwt_cookies
from flask_jwt_extended import get_jwt_identity
from flask_jwt_extended import create_refresh_token
from datetime import timedelta

from flask_cors import CORS, cross_origin

# Hash the password
from flask_bcrypt import Bcrypt

#  MongoDB setup
cluster = MongoClient("API_KEY")
db = cluster["UserData"]
user_collection = db["user_collection"]
post_collection = db["post_collection"]
test_collection = db["test_collecction"]

user_collection.create_index('username',unique=True)

app = Flask(__name__)


app.config["JWT_TOKEN_LOCATION"] = ["headers", "cookies", "json", "query_string"]
app.config["JWT_COOKIE_SECURE"] = False
app.config["JWT_SECRET_KEY"] = "super-secret"
app.config["JWT_ACCESS_TOKEN_EXPIRES"] = timedelta(hours=1)  
app.config['JWT_COOKIE_CSRF_PROTECT'] = False
app.config["JWT_CSRF_METHODS"] = [ "POST","PUT", "PATCH", "DELETE"]
app.config['JWT_ACCESS_COOKIE_PATH'] = '/'

CORS(app, supports_credentials=True)

bcrypt = Bcrypt(app)

jwt = JWTManager(app)

@app.route("/login", methods=["POST"])
def login_user():
    request_payload = request.json #if the key doesnt exist, it will return a None
    userData = request_payload['user']

    #  Find DB data
    try:
        existing_user = user_collection.find_one({"username": userData["username"]})

    except:
        return f"error! Database cannot be connected"

    #  If found user, check password
    if existing_user:            
        input_password = userData["password"]          
        database_password = existing_user["password"]

        # If match,will return true
        if bcrypt.check_password_hash(database_password, input_password):
            username_variable= existing_user["username"]
            access_token = create_access_token(identity=username_variable)
            response = jsonify({"msg": access_token},{"Welcome": username_variable})
            set_access_cookies(response, access_token)
      
            return response
        else:
            return("password not match")

    else: 
        
        return f"no_such_user"

@app.route("/protected", methods=["GET", "POST"])
@jwt_required()
def protected():
    
    getTheLoginNameFromToken= get_jwt_identity()
    return jsonify({"Congratulations, Login successful, you are": getTheLoginNameFromToken})


@app.route("/post", methods=["POST"])
@jwt_required()
def createpost():
    if request.method =="POST":
        request_payload = request.json #if the key doesnt exist, it will return a None
        print(request_payload)
        post_collection.insert_one(request_payload)

        return f"Post has been saved"

Post request function(React) not work

 const submitApplication = (e) => {
    e.preventDefault();
    axios
      .post(`${API_URL}/post`, {
        headers: {
          "Content-Type": "application/json",
          Authorization:
            "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTY1MjQ3MDI0MywianRpIjoiMjE3NWI3MTYtYjJiZS00OTFhLWI5MTYtZjVlMzQzN2UxZTJlIiwidHlwZSI6ImFjY2VzcyIsInN1YiI6ImFkbWluIiwibmJmIjoxNjUyNDcwMjQzLCJleHAiOjE2NTI0NzM4NDN9.AZyzOBlNimaAVQ26ZwKBgzw3TUTncBRUpbi0FOJwAg8",
        },
         title: title,
         description: description,
         content: content,
         slug: slug,
         imageLink: imageLink,
         category: {
           slug: category,
           id: category,
         },
      })
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
        console.log(error.response.data);
      });
  };

Post request function(React) work

const submitLogin = (e) => {
    e.preventDefault();
    
    axios
      .post(
        `${API_URL}/login`,
        {
          user: {
            username: username,
            password: password,
          },
        },
        { withCredentials: true, credentials: "include" }
      )
      .then(function (response) {
        // the access token will store in cookies automatically (http-only cookie) 
        Cookies.set("username", `${response.data[1].Welcome}`);

         // Redirect original page
         setTimeout(function () {
           window.location.replace("/login");
         }, 500);
      })
      .catch(function (error) {
        console.log(error);
      });
  };

Updated: Q1 solution

const submitApplication = (e) => {
    e.preventDefault();
    axios
      .post(
        `${API_URL}/post`,
        {
          title: title,
          description: description,
          content: content,
          slug: slug,
          imageLink: imageLink,
          category: {
            slug: category,
            id: category,
          },
        },
        {
          headers: {
            "Content-Type": "application/json",
            Authorization: `Bearer ${tokenCode}`,
          },
        }
      )
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
        console.log(error.response.data);
      });
  };



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source