django + varnish caching not being stored due to csrf tokens - django

I have a login form on my homepage. This is causing a csrf token to be set and this is meaning that my page is not being stored in the varnish cache.
How should I get around this?

You have two main courses: either give up using varnish to cache the page, or give up having a login form on the page. The CSRF token (which you don't want to lose) will prevent you from successfully caching the page in varnish; even if you take it into account, you're going to end up with a copy of the page for every single person visiting, which defeats the purpose of using varnish.
A solution halfway between the two is to cache the page without login form in varnish, and then insert the login form using Javascript. The main page will be cached, and you should be able to make the login form (pulled via AJAX) fast enough to not cause you problems. Another possible solution would involve putting the login form in an IFRAME, although that complicates matters yet further since you'd have to have something in the response to logging in which worked with Javascript in the main page (that included the IFRAME in the first place) to reload it suitably.

Related

Siege - How to test views that require login?

I am trying to use Siege to do stress testing on my django application. For static pages (e.g. landing page) it works just fine. However, 99% of the pages I want to test require that I be logged in.
How can I get Siege to login and test django views? The login page uses the Django Login form and view.
If it possible to test as one user logined in you can pass session cookie as Cookie header -H "Cookie: cookieValue". For more complicated scenario better to Apache Jmeter.
For basic HTTP authentication form, adding login=SomeUsername:somepassword to siege.conf directives worked for me. May be possible to use for other login schemes.

Single-page login in Django app

I'm currently using out-of-the-box django.contrib.auth to handle authentication in my Django app. This means that the user starts at a log in page and is redirected to the app on successful login. I would like to make my app single-page, including this login process, where a redirect doesn't happen, but maybe a "hot" template switch-out or some fancy client-side div magic (that still remains secure). My Google searching turned up pretty short, the closest solution dealing with putting a log in form on every page.
Any direction or ideas here would be much appreciated. I would obviously prefer to work within the existing confines of django.contrib.auth if possible, but I'm open to all solutions.
I'm not sure I understand your question completely. I think you want to have a single page. If so, put logic in your template that checks to see if the user is authenticated. If not, display a login form that POSTS to the appropriate django.contrib.auth view. You can supply an argument to this view to have it redirect back to your page. When you come back, the user will be authenticated, so you won't display the login form.
Have a look at Django-Easy-Pjax https://pypi.python.org/pypi/django-easy-pjax - it works like a charm and is well documented. Everything you like is being made with AJAX requests: links, forms using GET and forms using POST.
Essentially you only need to add a data-pjax="#id_of_the_container_where_the_result_goes" attribute in your a and form tags.
And the great thing about it: It updates the title and location bar of your browser.
One caveat: If you want to upload files in some form, this is not supported by Easy-Pjax, so you might want to use some workaround jQuery library for that.

Implementing Ajax requests / response with django-allauth

I am using django-allauth for one of my project. I would like to implement login/signup process via ajax. I would like to have customized signup form. I was going through their signupmixin and signup form. Sounds like I can write custom views for each action and map it to the url config. I am not sure what is the best way to do this.
Thank you so much for any help or advice on this.
It depends a bit on what you mean by ajax. If you just want to have a popup-style login/signup box on every page, then you can simply add the form to your base template and show it dynamically using Javascript in a popup box or so. If you keep the form action url to the original allauth urls then this will already give the feel of an ajax signin. You could also tweak things by using $.ajax or $.post to post to the original allauth views.
Something like the above is done on http://officecheese.com/ -- this is an allauth based site, though I am not affiliated with it.
If by ajax you mean that all authentication related views should be displayed via ajax, without causing a new document reload, then I am afraid you are a little bit out of luck. This simply is problematic for scenario's where e-mail verification, or OAuth handshakes are involed, as here you are typically navigating to a new URL from your mailbox, or redirecting to Twitter and so on.

Django: caching all but user auth in page

I'm experimenting with various Django 1.3 caching approaches to use for our landing page. This page has results from several database queries as well as user authentication. By far the best-performing solution has been to use the #cache_page decorator to cache the whole view function response. The problem is that user auth also gets cached.
I can create a key in the cache for each user but this seems wasteful; caching the same landing page over and over with the only difference being the user's authentication. I also used template fragment caching and low-level caching for all but the authentication but the performance was nowhere near as good as the #cache_page decorator approach.
Is there a way to get the performance of #cache_page without lots of redundant user-based caching?
Check out this blog post: http://www.holovaty.com/writing/django-two-phased-rendering/
Basically the technique is to wrap your user-specific segments in a template tag that prevents the template engine from rendering them, then cache, and then re-render the cached output to fill out the user details.
Django 1.5 includes a tag called verbatim which can be used instead of the custom raw tag in the post; you'll still need the custom CachedTemplateMiddleware or equivalent though.

Is Varnish compatible with Django Csrf protection?

I would like to put Varnish as a in front of a corporate website built with Django, to improve its performance. On every single page of the site there is a small contact us form. Other than that, the site is mostly static. The trouble is I can't figure out how to combine Varnish with Djangos Csrf protection. I suppose the same question applies to any sort of full-page caching with the Django csrf protection.
I suppose turning off the csrf middleware is a no-no - right?
matti
Normally I would suggest you to start using Django + Varnish ESI.
In case if you use only full page caching - I suggest you the following workaround:
Move forms loading to AJAX call (to POST request)
In your vcl file either mark only GET requests for lookup or mark POST requests for hit_for_pass.