Flasks logout_user() not working with React - python

I'm using Flask on backend and it works well when i making logout query via PostMan in browser. But the problem i met, when tried to connect it with React, which i'm using on frontend, is it returns Request failed with status code 401 ...
handleLogout.jsx
const handleLogout = async () => {
try {
let response = await PostService.userLogout()
setIsAuth(false);
sessionStorage.removeItem('access_token');
} catch (e) {
alert(e)
}
}
PostService.jsx
static async userLogout() {
const resp = await axios.get(lochost + "api/logout")
return resp.data
}
routes.py
#app.route("/api/logout", methods = ["GET"])
#login_required
def logout():
print(current_user)
logout_user()
return jsonify(msg = "Logged out successfully", status = 200)

Related

CSRF verification failed. Request aborted in Django rest framework sending the request from flutter

I've followed everything mentioned in both documentation of Django rest-framework and Flutter http but still getting the error ..here is my code :
Django
Settings
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
]
}
View
#csrf_exempt
#permission_classes(["isAuthenticated"])
#api_view(['POST'])
def chanage_image(request):
data = {}
if request.method == "POST":
token = request.META['HTTP_AUTHORIZATION'][6:]
lang = request.META['HTTP_LANG']
image = request.data['image']
main_user = Token.objects.get(key=token).user
app_user = AppUser.objects.get(main_user=main_user)
format, imgstr = image.split(';base64,')
ext = format.split('/')[-1]
data = ContentFile(base64.b64decode(imgstr), name='temp.' + ext) # You can save this as file instance.
app_user.image = data
app_user.save()
data = {"success": True, "details": AppUserSerializer(
app_user).data, "message": "Image changed" if lang == "en" else "تم تغيير الصورة"}
return Response(data, headers=get_headers())
URLS
path('chanage_image/', chanage_image,name="chanage_image"),
Flutter
Request
Map<String, dynamic> body = {
"image": base64Image,
};
Future<UserModel> changePlayerImage(Map<String, dynamic> body) async {
return await httpClient.post('api/user/change-image',
body: body,
headers: {'referer': 'https://www.l-dawri.com/'}).then((response) {
print(response.body);
return UserModel.fromJson(response.body);
});
}
but still in the end am always getting this error :
CSRF verification failed. Request aborted.
You are seeing this message because this site requires a CSRF cookie when submitting forms.
First you don't sent authorization token into header request while use from drf TokenAuthentication
Also into drf is better you use from class view api(like inheritance from APIView) replace def view's

How to display an error message on invalid url?

#app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
session['link'] = request.form.get('link')
link = YouTube(session['link'])
return render_template('video.html', link=link)
return render_template('index.html')
#app.route('/download', methods=['GET', 'POST'])
def download():
if request.method == "POST":
link = YouTube(session['link'])
itag = request.form.get('itag')
video = link.streams.get_by_itag(itag)
filename = video.download()
return send_file(filename, as_attachment=True)
return redirect(url_for('index'))
if __name__ == '__main__':
app.run(debug=True)
I want my youtube downloader code to display an error message when the user enters an invalid URL or if the video is unavailable. It is showing an internal server error if the user enters an invalid URL.
After changes:
#app.route('/', methods=['GET', 'POST'])
def index():
try:
if request.method == 'POST':
session['link'] = request.form.get('link')
link = YouTube(session['link'])
return render_template('video.html', link=link)
return render_template('index.html')
except:
return redirect(url_for('index'))
Now if the user enters the invalid URL the user gets redirected to the homepage but I want to Flash error message once the user gets redirected to the homepage.
Instead of you current API call, you can use the catch method with the new Fetch method in Javascript:
fetch('https://example.com/profile', {
method: 'POST', // or 'PUT'
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then(response => response.json())
.then(data => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});
The catch method triggers anytime when an error occurs. What you can do is specify different statements to output and check different crash criteria.
Sources:
Using Fetch

How do I make changes in a particular React component from a Flask server?

I hope my question is clear enough.
So, I have a React form in component A. I want to pass the fields using an AJAX request to a Flask server, which processes the data received and updates the DOM in component B.
Tried looking up several other SO pages but none of them answered the question. And I'm super new to both AJAX and Flask, so that doesn't help either.
My current code looks like this:
Component A:
import React from "react";
class InputForm extends React.Component {
claimRef = React.createRef();
handleSubmit = event => {
event.preventDefault();
const claim = this.claimRef.current.value;
this.props.addClaim(claim);
$.ajax({
type: "POST",
url: "/test/",
data: claim
})
.done(function(data) {
// self.clearForm();
})
.fail(function(jqXhr) {
console.log("failed to register");
});
};
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Claim:
<textarea name="claim" ref={this.claimRef} placeholder="Claim" />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
export default InputForm;
Flask server:
#!/usr/bin/env python
import os
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route("/")
def index():
return render_template('index.html')
#app.route('/test/', methods=['GET', 'POST'])
def test():
clicked = None
if request.method == "POST":
clicked = request
return render_template('test.html', clicked=clicked)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=os.environ.get('PORT', 3000), debug=True)
I've added a test.html file temporarily, which is supposed to simply print the data, but even localhost:3000/test just prints "None".
I get absolutely no errors in any part of the application, and I also get status 200 in the network tab of the webpage, which means that the data is being accepted.
How do I access the passed data and subsequently, print it in component B?
There is nothing wrong with your reactjs http post, however I would recommend you to use the fetch api. However, when you want to talk to the client from your server you have to use json.
Here is how you would make an http request to the server try this:
const data = this.claimRef.current.value;
fetch('/test/', {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data), // body data type must match "Content-Type" header
})
.then(response => response.json())
.then(data => console.log(data));
Once you create make the http post to the server, this is how you retrieve the data from the server (flask)
#app.route('/test/', methods=['GET', 'POST'])
def test():
clicked = None
if request.method == "POST":
data = request.json
print(data) #json data from client (reactjs)
return jsonify(data='test')
# jsonify returns http response as json
Try it and see what you get! I hope this helps and good luck!
Be aware of CORS
fetch api
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

The render do not render to the template

In the admin index page I bind a id to a button, and use jquery ajax to request a logout event:
$("#logout").click(function(){
$.ajax({
url:'/logout/',
type:'POST'
})
})
And in the frontend/views.py:
def logout(request):
if request.method == 'POST':
request.session['username'] = None
request.session['is_login'] = False
import app_admin.views as app_admin_views
app_admin_views.conn = None # clean the connection
print ('before logout')
return render(request,'frontend/login.html')
In the Terminal have printed the 'before logout', but the page do not render to the frontend/login.html, and I also tried use redirect, all failure.
In logout view function, return a redirect
return redirect('login-or-something')
In javascript AJAX request handle the redirect response,
function handleSuccess(data, textStatus, jqXHR) {
location.href = jqXHR.getResponseHeader('Location');
}
function handleError(jqXHR, textStatus, errorThrown) {
console.log(errorThrown); // send to some error log collectors
}
$.ajax({
url:'/logout/',
type:'POST'
success: handleSuccess,
error: handleErr
});

Django + Phonegap Authentication

I am building an application with Phonegap on the client side and a Django server on the backend. I am not able to authenticate the user. Here's my code.
$.ajax({
url: "http://192.168.0.101/userbase/login/",
type: "POST",
dataType: "json",
data: {"username": username,
"account": account,
"password": password,},
success: function (json) {
if (json.logged_in == true) {
window.location.href = "products.html";
}
else {
alert("Invalid Credentials. " + json.error);
}
}
});
This is the AJAX call to log in the user from the index.html. It is authenticated temporarily as in the views.py
# SOME CODE
login(request, user=user)
print(request.user.is_authenticated())
response = JsonResponse(response_data)
response['Access-Control-Allow-Origin'] = '*'
response['Access-Control-Allow-Methods'] = 'OPTIONS,GET,PUT,POST,DELETE'
response['Access-Control-Allow-Headers'] = 'X-Requested-With, Content-Type'
return response
prints True. But, when the window redirects to products.html and I make an AJAX request to my Django server and check if the user is authenticated or not, it returns False. I am not able to find the error.
Please help. Thanks.

Categories

Resources