Invalidating Django session in JS without access to the server - django

I need the ability to invalidate the Django session even if there is no Internet connection (or the server is down, or anything). The session cookie is by default httpOnly, and I don't like to change it, so simply deleting it is not an option. Is there any standard way to deal with this issue?
The relatively simple solution is to write a custom middleware on top of Django sessions. This middleware could add a secondary session token, say sessionid2, that would be acessible (and deletable) from Javascript. Both would be checked simultanously, so just one missing would invalidate the session. However, I would strongly prefer to use some of-the-shelf solution, if one exists.
The application is supposed to work as Chrome's Progressive Web App, so I'll be happy with a Chrome-specific solution if there is one.

Related

How to use react-router and Django templates

Folks,
I am pretty sure I am not the first one to stumble on this problem. But somehow I am unable to find any relevant resources out there.
Here is my issue, I have a backend in Django and my front completely written in Reactjs- React Router - Redux (nice combo right).
when entering the url webhost.com/, django provides me with a page with links to a bundle that is my whole react application and different stylesheets
The problem arise when I want to refresh a page, the browser still tries to query the server even though a route exists in my react-router configuration.
I had a look at the answer here (catch-all option) React-router urls don't work when refreshing or writting manually , but I don't quite understand it and I am afraid to have a new redux state everytime Django will provide the user with a new page.
You can setup up a wildcard url pattern that will render the same view that gets rendered when a request is sent to webhost.com. I don't know if that's going to retain your store though.

How to integrate Django Rest APIs with BackboneJS frontend for single page application

I am not able to comprehend what would be pros and cons of the following approaches in making a single page backbone application using RESTful APIs from Django Rest Framework.
Render the whole app from within Django's template.
Serve the backbone app from another server ie node server. With nginx in the front for both servers.
Serve the HTML/Templates and JS from a separate CDN.
What are the things to take care ie points of caution in each strategy. Is there any other way to tie them up which I am missing?
This is a very broad question, and really it has nothing to do with Django or Backbone. What you're really asking about is a "thick-client" architecture vs. a "thin-client" architecture. In other words, having your user interface rendered on the client vs. having it rendered on the server.
First, allow me to recap a few things to make sure we're on the same page. The "thin-client" approach is the traditional/old school model, and the model Django itself is based on. The server renders HTML, sends it to the client, and whenever the client wants to do something it sends data back to the server and asks for fresh HTML.
In contrast the more modern "thick-client" approach lets the client render all of the UI. Whenever the client needs to do something it makes an AJAX request to a (presumably REST-ful) API, powered by a library like Django REST Framework. That API just returns the relevant data, and leaves it up to the client to render it appropriately.
There are advantages and disadvantages to both approaches, but the thick-client approach is becoming more and more popular because:
network transactions are faster: because your server is only sending the exact JSON you need instead of a mess of HTML, the "payload" of the response is much smaller
you can fetch all data "behind the scenes"; this makes things appear faster to the user, and lets you implement UI paradigms (eg. infinite scroll) that a thin client can't
the client/server relationship is simpler, because the people writing server code never have to even think about HTML or any other presentation logic; they get to just focus on the data (which, being server engineers, is probably the part they're most interested in anyway)
This is why a lot of companies (including the one I work for) have all but abandoned Django proper in favor of API endpoints served by Django REST Framework.
So, if you want to go with a thick client architecture, Django should never serve anything except the very first HTML page (and even that could be served by ngnix if you wanted, since it's just static HTML). After that you'd use a Backbone.Router and Backbone.Views to render your site. Whenever you need new information from the server you'd fetch a Backbone.Model or Backbone.Collection (with its url property pointing to your Django REST Framework endpoint).
I can attest that this whole approach works great; the site I work on is very complex, with many endpoints, and Backbone + Django REST Framework handles it beautifully. The only (slightly) tricky part is caching: in the thin client approach the browser automatically caches pages for you, but since there are no "pages" in a thick client (just AJAX responses with data) there is no automatic caching. This means that if you want to cache data you'll need to do it yourself, for instance with a Backbone.Collection devoted to that purpose.
Hope that helps.
P.S. Back in the day Django REST Framework didn't handle Django authentication stuff (ie. logging in/out) quite the way we wanted, so we wound up serving one other page, our login page, from Django. However I'm pretty sure the current Django REST Framework handles authentication stuff much better now, so this likely won't be an issue for you.

Django: control access to "static" files

Ok, I know that serving media files through Django is a not recommended. However, I'm in a situation where I'd like to serve "static" files using fine-grained access control through Django models.
Example: I want to serve my movie library to myself over the web. I'm often travelling and I'd like to be able to view any of my movies wherever I am, provided I have internet access. So I rip my DVDs, upload them to my server and build this simple Django application coupled with some embeddable video player.
To avoid any legal repercussions, I'd like to ensure that only logged-on users with the proper permissions (i.e. myself and people living in the same household, which can, like me, access the real DVDs at their convenience), but denies it to other users (i.e. people who posted comments on my blog) and returns an HTTP 404.
Now, serving these files directly using Apache and mod_wsgi is rather troublesome because when an HTTP request for the media files (i.e. http://video.mywebsite.com/my-favorite-movie/) comes in, I need to validate against my user database that the person at the other end has the proper permissions.
Question: can I achieve this effect without serving the media files directly through a Django view? What are my options?
One thing I did think of is to write a simple script that takes a session ID and a video's slug and returns some boolean indicating if the user may (or may not) access the video file. Then, somehow request mod_wsgi to execute this script before accessing the requested URL and return an HTTP 404 if the script failed. However, I don't have a clue if this is even possible.
Edit: Posting this question clarified some of my ideas for search and I've come across mod_python's file wrapper extension. Does anyone have enough experience with that to validate that it is a viable solution?
Yes, you can hook into Django's authentication from Apache. See this how-to:
Authenticating against Django’s user database from Apache

Django Admin - Re-authentication?

I'm in a bit of a dilemma at the moment regarding Django's admin backend. The default authentication system allows already logged-in users that have staff privileges to access the admin site, however it just lets them straight in.
This doesn't feel “right” to me, and I'm wondering if it would be difficult to at least require a re-authentication of that same session in order to get into the backend.
Preferably though, it'd be good if the frontend sessions could be separated from the backend ones (though still using the same user objects), this would allow a clean separation of both parts of the site. Would this perhaps require two separate authentication backends? Would something like this be difficult to achieve?
Here's an idea: run the admin app on a different domain to the frontend. The cookies won't be valid in the other domain, so the user will have to log in again. All you'd need would be a separate Apache vhost and a basic settings.py that just has contrib.admin in INSTALLED_APPS.
You could probably implement a middleware that asks for authentication when accessing the admin site from a referer not in the admin site. It could log the person out and make them log back in, but even that wouldn't be necessary. Just require another password entry, and redirect them if it fails. It might involve setting a session variable, is_admin_authenticated or something.

Besides URL rewriting, what options are available for maintaining sessions without using cookies?

I've seen various options for URL rewriting here on Stack Overflow, and other places on the web, but was curious to see if there were other options.
This is speculation, as Cookies and URL Rewriting are the big two, but technologically, I think it'd be possible to:
do some massive hackery with javascript that captures all links and submits a form with information.
track the session on the server based on IP
Both have their downsides and holes obviously.
Session variables? At work, we are not allowed to use non session-cookies without a load of permissions.
You can either maintain state through a cookie or through a query parameter. The browser needs to be able to pass data to the web server somehow and those are the only two options.
I suppose that would depend on what technology you are using. In ColdFusion you can maintain session variables without cookies.
Using a client-side database storage, such as Google Gears (sqlite) ? Html5 is expected to include one (webkit already does it).