I am currently trying to do a fetch request when logged into the web app but i keep getting a .
87466804-e84d-413e-abd1-74dc56624149-ide.cs50.xyz/sell:1 Failed to load resource: the server responded with a status of 502 (Bad Gateway)
and then
sell:1 Access to fetch at 'http://87466804-e84d-413e-abd1-74dc56624149-ide.cs50.xyz/sell' from origin 'http://127.0.0.1:5000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
My Flask app looks like
#app.route("/sell", methods=["GET", "POST"])
#login_required
def sell():
ticker_symbols = helper_index.get_ticker_symbols(currently_owned_table)
#handles GET request
if request.method == "GET":
return render_template("sell.html", companies=ticker_symbols)
if request.method == "POST":
#handles submitted form
if "sell_form" in request.form:
#if form is submitted
return "thanks"
#handles fetch request
else:
the_request = request.get_json()
the_symbol = [the_request["symbol"]]
shares_available = helper_index.get_total_shares(the_symbol, currently_owned_table)
requested_shares = the_request["shares"]
print(requested_shares)
if int(requested_shares) <= shares_available[0]:
return "true"
else:
return "false"
I'm unsure how to fix this? and ideas appreciated
Flask-CORS does magic.
app.py:
app = Flask(__name__)
cors = CORS(app, resources={r"/*": {"origins": "*"}})
#app.route("/api/v1/users")
def list_users():
return "user example"
Related
I have a function-based view:
api_view(['POST'])
def scoring_logicapp_kickoff(request, prediction_id):
if request.method == 'POST':
url = "https://FAKEURL.net"
payload = json.dumps({
"prediction_id": prediction_id
})
headers = {
'Content-Type': 'application/json'
}
requests.request("POST", url, headers=headers, data=payload)
return Response(status=status.HTTP_202_ACCEPTED)
return Response(status=status.HTTP_400_BAD_REQUEST)
FAKEURL is actually a URL that sets off an Azure Data Factory logic app. I originally was getting a 403 error "Forbidden (CSRF cookie not set.)". I then wrapped the URL endpoint to quickly circumvent the issue:
path('logicapp-trigger/<int:prediction_id>/', csrf_exempt(views.scoring_logicapp_kickoff))
Now I'm getting the error: "AssertionError: .accepted_renderer not set on Response"
Any idea how to fix the original csrf error or the response error? I'm a bit stuck.
I have the following configuration for flask:
app.config['SESSION_REFRESH_EACH_REQUEST'] = False
app.config['SESSION_PERMANENT'] = True
I understood that since 'SESSION_REFRESH_EACH_REQUEST' is False, it will not send set-cookie in the response when session is not modified.
In the after_request I check if session was modified:
#app.after_request
def add_header(response):
if session.modified == False:
print(response.headers)
return response
It indeed wasn't!
No matter what I do, even when I explicit set session.modified = False, flask response have a set-cookie header with the session ID.
I need flask to not send set-cookie in the response because I want to connect my website with cloudflare, caching every response. How can I do it?
To remove the behavior of sending set-cookies in http header, I modified the "should_set_cookie" function of session interface, right after you create you app instance:
from flask.sessions import SecureCookieSessionInterface, SessionMixin
class CustomSessionInterface(SecureCookieSessionInterface):
def should_set_cookie(self, app: "Flask", session: SessionMixin) -> bool:
if (session.modified == False and request.method == 'GET'):
return False
else:
return True
app.session_interface = CustomSessionInterface()
This made sure it will not set-cookies if the session wasn't modified and is a GET request.
This is helping me a lot in cloud caching!
I have a DRF backend with a Vue frontend. It has been working for a while (alpha test), but I am trying to thoroughly test the authentication of the site.
I login as a test user, then go directly to the database and delete that user from the authtoken_token table. I then hit a backend endpoint to see what error I get.
I'm getting an AuthenticationFailed message, but it is an HTTP response, not JSON. Also, it is a "500 Internal Server Error" instead of a 401 or 403.
Looking at the handle_exception() method (rest_framework/views.py), I see that it is checking for NotAuthenticated and AuthenticationFailed exceptions, so it should match the actual exception of AuthenticationFailed.
def handle_exception(self, exc):
"""
Handle any exception that occurs, by returning an appropriate response,
or re-raising the error.
"""
if isinstance(exc, (exceptions.NotAuthenticated,
exceptions.AuthenticationFailed)):
# WWW-Authenticate header for 401 responses, else coerce to 403
auth_header = self.get_authenticate_header(self.request)
if auth_header:
exc.auth_header = auth_header
else:
exc.status_code = status.HTTP_403_FORBIDDEN
exception_handler = self.get_exception_handler()
context = self.get_exception_handler_context()
response = exception_handler(exc, context)
if response is None:
self.raise_uncaught_exception(exc)
response.exception = True
return response
How to ensure I get a JSON response?
I have a problem when I deployed django on Apache. I have a view :
#csrf_exempt
def login(request,id=-1):
if request.method == 'POST':
if 'HTTP_AUTHORIZATION' in request.META:
auth_header = request.META['HTTP_AUTHORIZATION']
encoded_credentials = auth_header.split(' ')[1]
decoded_credentials = base64.b64decode(encoded_credentials).decode("utf-8")\
.split(':')
username = decoded_credentials[0]
password = decoded_credentials[1]
if username is '' or password is '':
return JsonResponse({'Please enter username & password': 1})
info = Personel.validation(username,password)
if info == -1:
return JsonResponse({' page_not_found': 404})
if info == 0:
return JsonResponse({' permission_denied': 403})
if info == 1:
personpass = Personel.objects.filter(username=username,password=password)
dd=Personel.serializer.__get__(personpass[0])
data2 = json.dumps(list(personpass[0].serializer))
data2 = json.dumps(dd)
return JsonResponse(data2,status=200, safe=False)
I call it using this url
http://127.0.0.1:8000/views/login
on my development host (127.0.0.1:8000) when I call it and provide a user/password by http authorization it works fine.
Yesterday I deployed my site on server. it is windows and I am using Apache, When I call the above route it returns this error
The view didn't return an HttpResponse object. It returned None instead
Nothing is changed. My server is deployed fine and django admin page works fine. I can not find the reason why this happens
Well,
The problem was because apache does not pass http authorization to django. so I had to add these lines
# this can go in either server config, virtual host, directory or .htaccess
WSGIPassAuthorization On
into http conf
I have my rest-api set up in Django and am using React Native to connect with it. I have registered users and am able to generate tokens however I am unable to pass the token in the header of the GET request. My code is as follows:
try{
let response = await fetch("http://127.0.0.1:8000/fishes/auth/",
{
method: 'GET',
headers: {
// 'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': ' Token '+accessToken,
}});
let res = await response.text();
}}
I have been following this link http://cheng.logdown.com/posts/2015/10/27/how-to-use-django-rest-frameworks-token-based-authentication and have already verified that the response from the rest api is correct.
However on the phone with native react I get the following error in the console:
TypeError: Network request failed
at XMLHttpRequest.xhr.onerror (fetch.js:441)
at XMLHttpRequest.dispatchEvent (event-target.js:172)
at XMLHttpRequest.setReadyState (XMLHttpRequest.js:542)
What am I doing wrong in the GET code?
Alright 401 status code which means UnAuthorized.
For Django Rest Framework you must pass in the access Token as part of header for all your API requests.
Header Format will be
Key : Authorization
Value: Token <token>
You can see more here
http://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication
I think that you need change
'Content-Type' to 'content-type'
On lowercase
See This answer.
The same-origin policy restricts the kinds of requests that a Web page can send to resources from another origin.
In the no-cors mode, the browser is limited to sending “simple” requests — those with safelisted methods and safelisted headers only.
To send a cross-origin request with headers like Authorization and X-My-Custom-Header, you have to drop the no-cors mode and support preflight requests (OPTIONS).
The distinction between “simple” and “non-simple” requests is for historical reasons. Web pages could always perform some cross-origin requests through various means (such as creating and submitting a form), so when Web browsers introduced a principled means of sending cross-origin requests (cross-origin resource sharing, or CORS), it was decided that such “simple” requests could be exempt from the preflight OPTIONS check.
I got around this issue by handling preflight request, as stated by the OP.
Previously, in my middleware, I filtered out requests that did not include an auth token and return 403 if they were trying to access private data. Now, I check for preflight and send a response allowing these types of headers. This way, when the following request comes (get, post, etc), it will have the desired headers and I can use my middleware as originally intended.
Here is my middleware:
class ValidateInflight(MiddlewareMixin):
def process_view(self, request, view_func, view_args, view_kwargs):
assert hasattr(request, 'user')
path = request.path.lstrip('/')
if path not in EXEMPT_URLS:
logger.info(path)
header_token = request.META.get('HTTP_AUTHORIZATION', None)
if header_token is not None:
try:
token = header_token
token_obj = Token.objects.get(token=token)
request.user = token_obj.user
except Token.DoesNotExist:
return HttpResponse(status=403)
elif request.method == 'OPTIONS':
pass
else:
return HttpResponse(status=403)
Here is my Options handling
class BaseView(View):
def options(self, request, *args, **kwargs):
res = super().options(request, *args, **kwargs)
res['Access-Control-Allow-Origin'] = '*'
res['Access-Control-Allow-Headers'] = '*'
return res