Flask set_cookie not carrying over to other routes - python

I am having an issue with the SetCookie which I can't get it to work. I've seen too many SO topics but no success so far. Here is my situation:
I have an Ajax POST call which sends a token from my frontend (JavaScript) to my backend (Flask). This Ajax call send the token to the route /sessionLogin:
#app.route('/sessionLogin', methods=['POST'])
def session_login():
id_token = request.form['idToken']
csrfToken = request.form['csrfToken']
expires_in = datetime.timedelta(minutes=120)
expires = datetime.datetime.now() + expires_in
session_cookie = auth.create_session_cookie(id_token, expires_in=expires_in)
response = make_response(redirect('/home'))
response.set_cookie(
'session', session_cookie, expires=expires, httponly=True, secure=True)
return response
Then, on any 'protected route' I am basically getting the cookie 'session':
#app.route('/home', methods=['GET', 'POST'])
def home():
session_cookie = request.cookies.get('session')
# session_cookie always returning None
return render_template("index.html")
The problem is that when I sign in, get the token (from JS) and make the POST request, the request to /sessionLogin works great and I see the cookie 'session' in the response but any subsequent requests and by the way the redirect to /home does not include the cookie.
What I am missing here?
UPDATE (adding Ajax code):
firebase.auth().signInWithEmailAndPassword(email, pass)
.then(({user}) => {
return user.getIdToken().then((idToken) => {
console.log(user)
if (idToken) {
const csrfToken = getCookie('csrfToken')
return postIdTokenToSessionLogin('/sessionLogin', idToken, csrfToken)
.then(function() {
console.log('logged in.')
}, function(error) {
window.location.assign('/login');
})
}
})
})
const postIdTokenToSessionLogin = function(url, idToken, csrfToken) {
// POST to session login endpoint.
return $.ajax({
type:'POST',
url: url,
data: {idToken: idToken, csrfToken: csrfToken},
contentType: 'application/x-www-form-urlencoded'
});
};

Related

Cookies not create in browser django rest

I am trying to do authorization via access token in cookie. But i am having trouble setting cookies with react.
I set cookies in login:
class ApiLoginView(APIView):
permission_classes = [AllowAny]
def post(self, request, ):
password = request.data.get("password")
email = request.data.get("email")
user = authenticate(username=email, password=password)
if user:
try:
user.auth_token.delete()
except Exception as e:
pass
Token.objects.create(user=user)
response = Response()
response.set_cookie(key='access_token', value=user.auth_token.key, httponly=True)
response.data = {"result": True, "token": user.auth_token.key}
print(request.COOKIES)
auth.info("user {} login".format(user))
return response
else:
return JsonResponse({"error": "Wrong Credentials"}, status=status.HTTP_400_BAD_REQUEST)
If I auth into postman, everything goes well and the cookies are set.
print(request.COOKIES)
{'csrftoken': 'JZ1OOBZ0Ilxwo8Zt7DR0SbQ8MUMyNjiPhKYOIUQqY3OeXBEheeUoIa9MSI5S0HXG', 'access_token': 'd67ab794f8752ef02bcba5418bef2c6f87cb74f2'}
But if you do it through the frontend, I get only this
{'_ym_uid': '1612967974591822622', '_ym_d': '1614006098'}
My frontend request:
const response = await fetch("httpS://blablabla/api/auth/login", {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
});
I also have cors headers configured CORS_ALLOW_CREDENTIALS = True
I understood what was the matter, cookies do not work on localhost in chrome

Make permission bypass for Ajax requests from my website in Django Rest Framework

I made this API permission
def has_permission(self, request, view):
return request.user.is_authenticated and (
request.user.is_superuser or
models.AllowedToUseAPIList.objects.filter(user=request.user).exists()
)
where I check if user who asks for API is added into list of AllowedToUseAPIList.
But I also need to make AJAX requests from other pages of this website to this API. How can I change the permission to allow doing that?
I also pass my CSRF token into AJAX call but get 403.
I make Ajax call like that:
let csrf = $("input[name='csrfmiddlewaretoken']").val();
...
$.ajax({
url:"{% url 'api:ajax_api:save-mark' %}",
method: 'POST',
data:{
"csrfmiddlewaretoken": csrf,
"name": that.name,
"value": value,
},
success: function (data){
...
}
})
After all, I get 403 Permission Denied.
Try adding a parameter that tells the view when a bypass is allowed:
js:
$.ajax({
url:"{% url 'api:ajax_api:save-mark' %}",
method: 'POST',
data:{
"csrfmiddlewaretoken": csrf,
"name": that.name,
"value": value,
"bypass" : true, // add this parameter
},
success: function (data){
...
}
})
python:
def has_permission(self, request, view):
# check if request was triggered by ajax:
ajax_bypass = 'bypass' in request.POST and request.POST['bypass']
# check if use is a superuser:
user_is_superuser = request.user.is_superuser
# check if user is in allowed list:
user_is_authorized = models.AllowedToUseAPIList.objects.filter(user=request.user).exists()
return ajax_bypass or user_is_superuser or user_is_authorized

How come my data does not log onto console reactjs and flask

I am trying to log my data into the console from my fetch function. I am currently able to log the response to the flask server but not on the react side. I have tried to include the headers in the fetch function however that does not seem to work. As I am still getting an error:
Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0
App.py
from flask import Flask, request, jsonify
from flask_cors import CORS, cross_origin
app = Flask(__name__)
CORS(app)
#app.route('/api', methods=['GET','POST'])
def api():
if request.method == 'POST':
username = request.form['username']
email = request.form['email']
occupation = request.form['occupation']
print('Username: ' + username + ' Email: ' + email + ' occupation: ' + occupation)
print('Json ', (jsonify(username)))
return {"username": username}
else:
return {"username": username}
App.js
import React, {useState, useEffect} from 'react';
import Form from './components/Form'
import './App.css';
function App() {
const [initialData, setInitialData] = useState ([{}])
useEffect(()=> {
fetch('/api',{
headers: {
method: 'GET',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}).then(
response => response.json()
).then(data => console.log(data))
});
return (
<div className="App">
<Form/>
</div>
);
}
export default App;
The problem is that your fetch is yielding a 500 error. Thus, the response is something like:
<!DOCTYPE HTML.....
the reason is you are sending a GET request, so it fails the if request.method == 'POST': test. So, it tries to respond with return {"username": username}, but username is not defined in the else branch of the conditional.
Also, you might want to use:
return jsonify( {"username": username} )
to make sure you are sending an application/json mimetype response.

How to send out an AJAX request to Flask

I'm trying to send an AJAX request to my server to obtain a string and save it.
This is my relevant JS:
var token = "";
$.ajax({
type: 'GET',
url: 'payment_demo.py',
success: function(data) {
token = data;
},
});
This is my relevant Python (Flask):
#app.route('/')
def home():
return render_template('official_checkout_page.html')
#app.route("/", methods=["GET"])
def client_token():
return gateway.client_token.generate()
The HTML and JS both are loaded, but I get a 404 not found on the ajax URL (payment_demo.py).
Right now the locations are /payment_demo.py, /static/official_checkout_page.js (the JS file), /templates/official_checkout_page.html (the HTML file, if necessary). What am I doing wrong?
the ajax request just get data from the spesifik url from server/api resource, please try this code
$.ajax({
type: 'GET',
url: '/api/token',
success: function(data) {
token = data;
},
});
the example Flask code from backend server
from flask import jsonify, render_template
#app.route('/')
def home():
return render_template('official_checkout_page.html')
#app.route("/api/token", methods=["GET"])
def client_token():
return jsonify({"data":gateway.client_token.generate()})

Why does this Python Flask router return a 400 error when pinged by a crossdomain AJAX call?

I have the below Python Flask router:
#app.route('/create', methods=['GET', 'POST'])
#crossdomain(origin='*')
def create():
if request.method == 'POST':
print(request.form)
title = request.form['title']
url = request.form['url']
new_mark = Mark(
title=title,
url=url
)
new_mark.save()
return new_mark
When I do an ajax call (below) it responds with a 400 error.
$.ajax({
type: 'POST',
url: 'http://localhost:5000/create',
data: {
'title': sender.title,
'url': sender.url
},
xhrFields: {
withCredentials: true
},
dataType: 'json'
});
When I try printing out request it prints an empty immutableMultiDict. Any idea why it is giving this 400 and why there is no data?
Your ajax call is sending json-encoded data. I guess you should decode.
import json
data = json.loads(request.data)
print data.get("title")
I am stupid. I was not actually sending any data because sender.url and sender.title did not contain any values -_-.

Categories