I have a Django 1.6 app and I'm facing a problem with double submissions.
I could use the ideas spread all over here like: redirections, tokens, etc. (I got a JS prevention but I don't trust it) but after the submission I have to make another request to an API. The external API request takes let's say 20 seconds so there's plenty of time to play with the submit button.
The best solution I got right now is to save the CSRF (or any other unique token) in the DB and check if that token exists, if so 'kill' the request.
But that's the thing, can I kill the request? I can't respond with a 500, 404 because it's going to be delivered to the browser faster than the first/original request that does the API call.
Is there a way to kill/drop/pend a request with Django? Maybe this idea is crappy? Please share your knowledge.
I hope my English is understandable.
Related
My objective is to create a Flask API that allows for the following three pieces of functionality:
1- User A can make requests and each request has a deadline associated with it. In my mind, this is a simple post request with a unique ID, and a due date/time. This can probably get held in memory or saved to a DB.
2- User B gets notified of the request and has x time to respond to the request. The time is the same as the one in the first request. This user must upload an image to satisfy the request above.
3- User A can check the image, and either accept or reject it, the results of which get logged.
I have a few pieces of logic built out, but nothing impressive. What i am looking figure out is how to orchestrate this within Flask. Is there a particular pattern i should be researching, or any guidance on similar examples i can use?
The front end for this will be a telegram application.
I am developing an application with flask, which has a page with a map drawn on it, it is generated by a JSON, when a change is made on the map by the user it sends the change to the server and this makes a response to the user that made the request.
What i want is that when making the response it is made to all the users that are connected to the page so that the information is refreshed, and not only for the one who made the request.
you will have to implement some registration mechanizm for clients, so when an update occur, you iterate over clients in the registration list and send them the new data
to implement the actual push, you can do it with web-sockets (best for high throughput and small messages) or you can use server-send-event for that (much simpler implementation mainly because it's riding on the http protocol)
there are other approaches using more advanced techniques, but, those 2 are the simplest and basic ones
What you are searching for is notification in push
im guessing one of the possible options for you is to make you javascript code \ or html to send a request every few minutes to check for new json
it can be simple done with ajax and interval
I'm making a new RESTful API in Flask that should accept both GET (for requesting the resource) and PATCH (for performing various incremental, non-idempotent updates) for a given object. The thing is that some of the data that's patched in must be authenticated, and some shouldn't be.
To clarify this with an example, let's say I'm building an app that let's everyone query how many times a resource has been clicked on and how many times its page has been viewed. It also let's people do an update on the resource in javascript saying the resource was clicked again (unauthenticated, since it's coming from the front-end). It additionally let's an authenticated backend increment the number of times the page has been viewed.
So, following RESTful principles, I'm thinking all three actions should be done on the same path-- something like /pages/some_page_name which should accept both GET and PATCH and should accept two different kinds of data with PATCH. The problem is that in Flask, it looks like authentication is always done with a decorator around a method, so if I have a method like #app.route('/pages/<page_id>', methods=['GET', 'PATCH']), my authentication would be done with a decorator like #auth.login_required for that whole method, which would force even the methods that don't require authentication to be authenticated.
So, my question is three-fold:
Am I right in structuring all three actions mentioned under the same path/ is this important?
If I am right, and this is important, how do I require authentication only for the one type of PATCH?
If this is not important, what's a better or simpler way to structure this API?
I see several problems with your design.
let's say I'm building an app that let's everyone query how many times a resource has been clicked on and how many times its page has been viewed
Hmm. This isn't really a good REST design. You can't have clients query select "properties" of resources, only the resources themselves. If your resource is a "page", then a GET request to /pages/some_page_name should return something like this (in JSON):
{
'url': 'http://example.com/api/pages/some_page_name',
'clicks': 35,
'page_views': 102,
<any other properties of a page resource here>
}
It also let's people do an update on the resource in javascript saying the resource was clicked again
"clicking something" is an action, so it isn't a good REST model. I don't know enough about your project so I can be wrong, but I think the best solution for this is to let the user click the thing, then the server will receive some sort of a request (maybe a GET to obtain the resource that was clicked?). The server is then in a position to increment the clicks property of the resource on its own.
(unauthenticated, since it's coming from the front-end).
This can be dangerous. If you allow changes to your resources from anybody, then you are open to attacks, which may be a problem. Nothing will prevent me from looking at your Javascript and reverse engineering your API, and then send bogus requests to artificially change the counters. This may be an acceptable risk, but make sure you understand this may happen.
It additionally let's an authenticated backend increment the number of times the page has been viewed.
Backend? Is this a client or a server? Sounds like it should be a client. Once again, "incrementing" is not a good match for REST type APIs. Let the server manage the counters based on the requests it receives from clients.
Assuming I understand what you are saying, it seems to me you only need to support GET. The server can update these counters on its own as it receives requests, clients do not need to bother with that.
UPDATE: After some additional info provided in the comments below, what I think you can do to be RESTful is to also implement a PUT request (or PATCH if you are into partial resource updates).
If you do a PUT, then the client will send the same JSON representation above, but it will increment the corresponding counter. You could add validation in the server to ensure that the counters are incremented sequentially, and return a 400 status code if it finds that they are not (maybe this validation is skipped for certain authenticated users, up to you). For example, starting from the above example, if you need to increment the clicks (but not the page views), then send a PUT request with:
{
'url': 'http://example.com/api/pages/some_page_name',
'clicks': 36,
'page_views': 102
}
If you are using PATCH, then you can remove the items that don't change:
{
'clicks': 36
}
I honestly feel this is not the best design for your problem. You have very specific client and server here, that are designed to work with each other. REST is a good design for decoupled clients and servers, but if you are on both sides of the line then REST doesn't really give you a lot.
Now regarding your authentication question, if your PUT/PATCH needs to selectively authenticate, then you can issue the HTTP Basic authentication exchange only when necessary. I wrote the Flask-HTTPAuth extension, you can look at how I implemented this exchange and copy the code into your view function, so that you can issue it only when necessary.
I hope this clarifies things a bit.
I would like to maintain statelessness but I also don't want to call my login function on each authenticated request. Would using tornado's secure cookie functionality be feasible for storing the userid in each request for a mobile app? I'm trying to keep performance in mind, so although basic http authentication would work, I dont want to call a login function on each request to get the users id.
I am assuming that your authentication function talks to a database and that each page in you app hits the database one or more times.
With that in mind, you should probably just authenticate each request. Many cloud/web applications have multiple database queries per page and run just fine. So when performance does get to be problem in your app (it probably won't for a long time), you'll likely already have an average of n queries per page where n is greater than 1. You can either work on bringing down that average or work on making those queries faster.
I order to get access to the Facebook API on behalf of a user, one must get an OAuth access_token, the process is well documented (albeit it appears to be some undocumented requirements from FB) but from time to time I get this "Error validating verification code." when trying to exchange a validation code for an access_token.
There seems to be a lot of people having such trouble and most of the time the redirect_uri seems to be the issue, but here the redirect_uri is fine (it's exactly the same as the one passed to the auth dialog, ends with a slash and do not have funky characters or a trailing query string, I read almost all threads on SO about this issue and none of the proposed solutions did solve my problem)
What is the most intriguing is that when I check my logs, where I write the exact request url I use, and manually try it to get the access token, then it works. It is like the request is failing when the user logs in but works after some time.
So the fact that it is working after all seems to indicate that the request is fine but there is a problem on the Facebook side, like if there was some replication involved that did not complete between the time the auth dialog do it's thing and I try to exchange the code for a token.
I put in place a retry mechanism, hoping that the delay between two calls would be enough and the second call would succeed, but it doesn't work either.
Also, it's working most of the time and I cannot tell any difference between when it works and when it fails, only the user changes.
Any suggestion would be greatly appreciated.
I just bumped into this issue and solved it.
The issue was that I specified the redirect_uri in the oauth call to be http://apps.facebook.com/myapp/ instead of https://apps.facebook.com/myapp/ .
One thing that was kind of odd is that the exact same parameters worked if I entered them into the browser address field, but not as a server side request from the application.
It is possible on a per user basis to specify if you want to browse Facebook with or without HTTPS, so I recommend that you test with the setting at both modes when you test your authentication flow.