Search code examples
reactjssessionflaskpython-requestsaxios

Flask Session does not hold any value between Requests


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


Solution

  • 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