I wrote several APIs using Flask-RESTful and several react modules for testing purposes. Ideally, if I stored some info in session through a request, python should be able to detect whether there is such session even in other API entries with code, like
if session:
return jsonify({'user': session['username'], 'status': 2000})
return jsonify({'user': None, 'status': 3000})
However, the problem I met was within a single request, say login request, session was indeed properly used and username
was also stored in the session —— for example,
from flask import session
...
# login API
class UserLoginResource(Resource):
@staticmethod
def post():
...
... # a user object (model) is defined
session['username'] = user.username
return jsonify({'status': 2000, 'user': session['username']})
with this code, it returned the exact username from session, which meant info was stored. However, when I made another get request from react side to the index API, like
from flask import session
...
# index API (without any practical use)
class IndexResource(Resource):
@staticmethod
def get():
if session:
return jsonify({'username': session['username']})
In this case, the response was None, cuz the API didn't detect any session.
// makePostRequest Function
makePostRequest = (e: any) => {
e.preventDefault()
const payload = {
'email': this.state.email,
'password': this.state.password
}
fetch('http://127.0.0.1:5000/api/login', {
method: 'POST',
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
}).then(res => res.json())
.then(res => {this.setState({
status: res['status'],
username: res['user']
})})
.catch(err => console.log(err))
}
This is the way I make login post request. If login successful, it returns status code 2000; and if the status code is 2000, it means the program has gone through the code session['username']=_the_username_
. And I should be able to extract username data from session storage when accessing Index page.
componentDidMount = () => {
fetch('http://127.0.0.1:5000/api')
.then(res => res.json())
.then(res => this.setState({
user: res['user'],
status: res['status']
}))
}
This is how I make a get request on the homepage module. However, the user
is always None and status
is always 3000
This may be just improper use of session, but I don't know how to actually correctly use the session in flask. So, what was the mistake here?
Update:
So, I added a GET request within class UserLoginResource(Resource)
like this
class UserLoginResource(Resource):
@staticmethod
def post():
... # identical to the previous code
@staticmethod():
def get(): # url: http://127.0.0.1:5000/api/login
session['username'] = 'user_a'
return jsonify({'message': 'session set'})
And I made a get request in react side to http://127.0.0.1:5000/api/login
and got the message: session set
. However, when react then accessed http://127.0.0.1:5000/api
, the result remained to be status
3000 and None username.
Then, I directly accessed the url http://127.0.0.1:5000/api/login
and then accessed http://127.0.0.1:5000/api
and there we go we had the username user_a
and status 2000
.
So, I think the problem here might be that the backend didn't recognize the browser that was accessing it was the same person, or it might be others.
Also, I checked if it was something wrong with componentDidMount
, but unfortunately componentDidMount
wasn't the source of error — after I turned it into a normal function triggered by onClick
, still it didn't work.
How to fix this?
fetch
does not supports cookie by default, you need to enable it using credentials: 'include'
makePostRequest = (e: any) => {
e.preventDefault()
const payload = {
'email': this.state.email,
'password': this.state.password
}
fetch('http://127.0.0.1:5000/api/login', {
method: 'POST',
credentials: 'include',
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
}).then(res => res.json())
.then(res => {this.setState({
status: res['status'],
username: res['user']
})})
.catch(err => console.log(err))
}
Enable cors on server using pip install flask-cors
Then Add this to app.py
, where you initialize your app
from flask_cors import CORS
app = Flask(__name__)
CORS(app)