I am developing an AngularJS website that uses an API backend on a different domain.
The front-end website is hosted at: www.example.com
The API is hosted at: api.example.com
I use Angular's $http.post to make an authentication request to the API which sets a cookie. I then make a secondary $http.get call to the API and the cookie that was set from the POST request isn't being sent back to the server. It looks like the cookie is getting lost somewhere.
The API is a Flask Python app and I'm using flask-cors to enable cross-domain calls. The Access-Control-Allow-Origin header is set to http://www.example.com The domain on the cookie being set is api.example.com
I have setup the application to run under one domain using nginx and url rewriting. So the front-end website is located at www.example.com and the API is accessed by www.example.com/api/ and the cookies are being saved/used as expected.
I can't tell whether this is a problem with my front-end or API website configuration.
Since you are sending the http requests from another domain, you need to make sure that your $http is able to send cookies. In your app's config, add:
$httpProvider.defaults.withCredentials = true
This will allow AngularJS to send your browser's cookies to the server.
Related
I want to protect my Flask REST endpoints using Okta and OpenID connect.
I have seen how to do it for routes that are views of the application, but is there a way to integrate Okta with REST endpoints? When I make calls to my API, I get the html for Okta as a response, even if I'm logged in in the browser.
What HTML do you get from Okta? in one case you might get a HTML page with a self-submitting form that is meant to be sent back to your client, and that's normal.
But at the same time, the openid-connect implementation in the API is different from your client applications. The API should not deal with user-redirects, instead it should only listen for access-tokens in the authorize request header. The API should for the received tokens validate them against Okta.
To add token to request, then see this question Flask Rest API - How to use Bearer API token in python requests
I am writing a Python program part of which authenticates with OAuth 1.0 to access a privileged API. I have figured out how to get the authorization URL. After signing in, the browser redirects to http://localhost which I registered as the callback with the provider. How do I get the request to localhost and continue with my bot? I figure I need to have a http server of some sort. I would rather not install a full Apache server. What is a lightweight alternative that can receive the request and forward the token to my bot code to continue with API calls?
I'm using Typeform to send a POST request to a Webhook on my server.
I'm looking at the sample request they give and it doesn't look like they are including a Referer header, so my Django site is blocking their request.
Is there a way to whitelist their domain so that they can keep sending this without the referer?
I know I could use csrf_exempt but that would not be ideal.
I have the domain both in CSRF_TRUSTED_ORIGINS and CORS_ORIGIN_WHITELIST.
We have this setup:
Central Django server, CSRF and login enabled. Except for the login no action may be performed without logging in previously.
An Angular2 client which connects for almost every call to the central server. The login on the central server is executed from here. CSRF token is available and authentication works.
Another small server which takes files. It is also Django but not CSRF enabled. The client sends files to this server which the central server may never possess or even see. The file upload (using form-data and POST) works fine. However, after a file upload has been completed, we would like this small server to call the central server notifying it of the successful upload.
The problem is the last step. The central server refuses the call, saying we need to be logged in. Can we in any way make the central server believe that the request came from the user who logged in with the Angular2 client? How do we have to set up the CSRF token? We are sending the user's CSRF token he got in the client to the small server.
We are using the python-requests library, Python 3 and Django 1.10.
This is the code we currently have on the small server:
url = settings.CENTRAL_SERVER_URL + 'path/to/endpoint'
# 'request' is the original request object from the Angular2 client
token = get_token(request)
# Call to 'post' results in error code in response ('not logged in')
response = requests.post(url, data=data, headers={'X-CSRFToken': token, 'Referer': url})
I assume the problem is the 'headers' definition. Can it be done at all?
(CSRF enabled = uses CsrfViewMiddleware)
Turns out I was on the right track. It is most important to include the session ID the client got when logging in also in the new request to the central server.
Here is the code:
url = settings.CENTRAL_SERVER_URL + 'path/to/endpoint'
http_x_token = request.META['HTTP_X_CSRFTOKEN']
csrftoken = request.COOKIES['csrftoken']
session_id = request.COOKIES['sessionid']
response = requests.post(url, data=data,
headers={'X-CSRFToken': http_x_token, 'Referer': url},
cookies={'csrftoken': csrftoken, 'sessionid': session_id})
The session ID should always be present in the request from the client.
SessionMiddleware in Django checks for this. If the session ID is present, the user can be found and everything else works as if I was making a request from the client.
I have an API Key for a Google API that I would like to use in all my requests to it. Some of these requests will originate from within a Google App Engine (Python 2.7) application. I had planned to use the UrlFetch library to complete the POST request, basically as follows:
headers = {'Content-Type': 'application/json'}
payload = {'longUrl': request.long_url}
result = urlfetch.fetch([API_REQUEST_URL],
method=urlfetch.POST,
payload=json.dumps(payload),
headers=headers)
json_result = json.loads(result.content)
I had set a referrer restriction on my API Key to *.[my-app].appspot.com/* with the hope that this would protect my API Key from unauthorized use and negate the need to update an IP-based key restriction (as App Engine IPs change all the time).
This approach as failed me though, because it seems that urlfetch does NOT specify a value for referrer on its own. I assume I could add my own referrer, but then so could anyone else. The approach isn't very secure.
What is the best practice? How should I restrict the key given that I'm using urlfetch from within App Engine? If I do use an HTTP Referrer restriction, which address do I use?
Many thanks.
You got like this error message?
Requests from referer <empty> are blocked.
urlfetch seems not to attach Refer automatically, so you should set Refer in your request header.
headers = {'Content-Type': 'application/json','Referer': '*.[my-app].appspot.com/*'}
As you observed the referrer header can be faked, so setting a referrer restriction on your API Key is rather useless to start with.
But you can add a check based on the X-Appengine-Inbound-Appid header, which is sanitized by the GAE infrastructure and precisely identifies the app. From Issuing a request to another App Engine app:
When issuing a request to another App Engine app, your App Engine app
must assert its identity by adding the header
X-Appengine-Inbound-Appid to the request. If you instruct the URL
Fetch service to not follow redirects, App Engine will add this header
to requests automatically.
To instruct the URL Fetch service to not follow redirects, set the
fetch follow_redirects parameter to False.
Note: If you are making requests to another App Engine application, use its appspot.com domain name rather than a custom
domain for your app.