1

I'm a rookie web developer and I am trying to implement a Flask + React app. In React, I have a form that asks for user_id and password. After the user enters the required data, React (Axios) sends it to my backend with the function updateDoneStatus as shown (it calls getName to pull the derived data):

 getName = () => {
     axios.get('http://127.0.0.1:5000/data')
      .then(res => {
            const name = res.data['name'];
            this.setState({name: name})
      }).catch(e => {
        console.log(e);
    });

 updateDoneStatus = () => { 
     this.setState({done: true})

     axios.post("http://127.0.0.1:5000/login",{
          data: {
              id: this.state.id,
              pw: this.state.pw
          }
      }).catch(e => {
         console.log(e);
      }).then(this.getName)};

When the user completes the form, my backend manages to get the sent data and starts web scraping as shown:

from flask import *
from flask_session.__init__ import Session
import requests
from bs4 import BeautifulSoup
from flask_cors import CORS
import re

app = Flask(__name__)
CORS(app)
app.config['SECRET_KEY'] = 'super secret key'
userID = ""
userPW = ""

@app.route("/login", methods=['POST'])
def getData():
    nameArr = []
    if request.get_json() != None:
        data = request.get_json()
        userID = str(data["data"]["id"])
        userPW = str(data["data"]["pw"])

        login_data = {
        'userid' :  userID,
        'pwd' : userPW,
        'Submit' : 'Sign In'
        }

        with requests.Session() as s:
            url = 'SOME URL'
            r = s.post(url,data = login_data)
            newUrl = 'SOME OTHER URL'
            a = s.get(newUrl)
            src = a.content
            soup = BeautifulSoup(src,features="html.parser")
            text = soup.get_text()
            nameArr = re.findall("some regex",re.findall("some regex",text)[0])

            session.permanent = True
            session["name"] = nameArr[0]
            session.modified = True

            return {'name' : session["name"]}
    else:    
        return {'name' : "it's not saved to session"}



@app.route("/data", methods=['POST', 'GET'])
def sendData():
    if "name" in session:
        return {'name': session["name"]}
    else 
        return {"name was not in session :("}

From my testings, I can see that it successfully logins to the desired URL and can get the scraped data, so there is no problem with sending data to the backend or web scraping with that data.

As far I understood from the documents of sessions in Flask, my implementation should hold data in session["name"], and store it until the user closes the browser. But whenever I want to send data to my frontend by using sendData(), it always prints "name was not in session :(", meaning it wasn't able to find the key "name" in session.

Some guesses why this is happening:

  • Session resets itself after each request.
  • Maybe it creates a new session each time I make a request.
  • Maybe the library "requests" and the Flask "request" are intersecting.

I think I didn't quite understand how sessions work, and I couldn't find enough information online.

I know I am missing something, can someone help?

Also, I read that session stores data in the server, is there a possible way to store data in clients browser (like cookies), if so how do you implement such thing? If you could explain it by implementing it to my own code that would be great!

(if you need any other information please let me know)

Thanks

atahanksy
  • 62
  • 2
  • 9
  • 1
    I also faced the same problem, but my frontend was Angular, instead of React. After lot of search, I found that, probably, this cannot be achieved, so I gave up. This is happening because your frontend and backend are hosted in different port, so flask assumes request is been made from different client every time. So, what you can do is first store the data in a cookie, then for every request you send this stored cookie data to the server. – ngShravil.py Mar 20 '20 at 08:14
  • @ngShravil.py thank you for your response, but how do I send cookies to my frontend port, I've tried resp = make_response("setting cookie") resp.set_cookie('name',nameArr[0]) but same happens – atahanksy Mar 20 '20 at 10:54

3 Answers3

2

As from our discussions in comments, we came to know that sessions don't persist between the API calls, if both frontend and backend are hosted in different ports.

Now sending cookies from Flask to React frontend also cannot be achieved, because of the same reason. It only works for Flask frontends.

You can do one thing, what ever you want to set as cookies, that you can send it in response from Flask, and from React you can set those cookies. You'l have to send this value to Flask for every request. I am not familiar with React, but I did like below in my Angular app (this is the very basic way):

document.cookie = 'token='+result.token

In angular you can do this easily with third party library also, the following like will help you : https://itnext.io/angular-8-how-to-use-cookies-14ab3f2e93fc

And in React, this link will help you : https://stackoverflow.com/a/43684059/6635464

ngShravil.py
  • 4,742
  • 3
  • 18
  • 30
  • Thank you, however sending data from react to my flask backend is not a problem though. The problem is : when Flask gets that data it uses it to web scrape and obtain some other data. In my frontend when I request that obtained data, I get nothing back since it is not saved to somewhere. I tried sessions, as you said it's not compatible with React. And if I understood correctly, using cookies won't help with my situation, or am I wrong? – atahanksy Mar 20 '20 at 20:26
  • I hope this was helpful. As the OP was mainly about sessions and cookies, could you post another question regarding web scrapping, as I am not familiar with this. – ngShravil.py Mar 21 '20 at 07:16
1

You are sending cross-origin requests, which by default do not allow cookies. Try to initialize Flask-CORS as follows:

CORS(app, supports_credentials=True)

More information: https://flask-cors.readthedocs.io/en/latest/api.html#using-cors-with-cookies.

Miguel Grinberg
  • 65,299
  • 14
  • 133
  • 152
1

I'm also using React with Next.JS as frontend and Flask as backend.

The issue is most likely due to CORS request, since your React frontend and Flask backend are not on the same port.

And using Flask-CORS is the way to go, the same confirmed as @Miguel

e.g. CORS(app, supports_credentials=True)

I'm using a fetch to send request in React, so including credentials: "include" will do the job

ffyuanda
  • 11
  • 2