how to use django_csrf for mobile application - django

I am writing a mobile application for a django website. i understand that every form in django has a CSRF token key for protection. when use browser to navigate the site, the server render a key for the user.
What i am confused is for mobile application, we dont need view the presetation layer from the site. I just wanna do a HTTP post to send data. I know i can use csrf_exempt to disable the csrf for that form. or i can make another view to render the csrf token for me, but this way i need extra parsing and http request. so is there a nicer way to do it?
Thanks for your time

If your mobile app is rendering a template you can add {% csrf_token %} into the template that renders the form. If you're not using a form and instead just posting data you can create the token as above and then simply post it's value with the data. And if you're not using a template to create the mobile app's markup well then use csrf_exempt (if say you're just posting data to the server periodically).
Obviously there has to be a view to process the posted data, but even if you're using a generic view for that you could still wrap that view (in your urls.py for example) and gain the use of csrf_exempt

Related

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.

Duplicate/Post django form on a non django website

I have a django site that has a donate form on it. This site handles only the internal donations by the organization. They have a public facing site that is not django driven. They want to have the same donation form for public users to submit donations through and have it get posted into the djagno sites database.
Is there anyway to have a non django site post form data to my database? Can iframe handle something like this?
EDIT:
The other problem I have is that this form has logic built within it. Based upon their address I trigger an ajax request to give a list of possible choices from the database for a select field. So this may further complicate things
The only problem will be with CSRF protection. You can't implement CSRF if you actually intend posts coming from an external site. Just decorate your form handler view with csrf_exempt.

Cross-domain redirect to a partially filled form on Django web application

I have an HTML form in my Django web application (NOT implemented using Django forms) that does POST request.
Now I want to implement a feature so that other web apps, not necessarily django, from different domains, can send some data to my application and get redirected to the web page with this form, partially filled with that data (the data can be JSON).
Besides redirecting, after the user clicks submit on my form, I would also want to send a message to the other server with some short text information.
I am not sure what is the best way to implement this. REST interface like Piston?
Could you give me some general directions I should follow?
You should create a view that handles the POST data from the form and the external web apps.
You should be able to check whether the data you are getting in the view is coming from your site or another by checking request.META['HTTP_REFERER'].
If it is from your site, you can just handle the form as you usually would.
However if it is from an external site, you would instead render the template with the form in it. You can put the information you got from the external site into the context, so you can pre-fill the form in the template.
You should also include a flag in the form to say that this was from an external site, something like:
<input type="hidden" name="external_site_url" value="{{ external_site_url }}">
After that form is submitted, you can check for the existence of external_site_url. If it exists you can then send the message to the other server.
Note, because you want other apps to use your view, you'll have to disable CSRF protection on the view (https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#csrf-protection-should-be-disabled-for-just-a-few-views).
Also, by allowing other apps to use your view, you are opening yourself up to a lot of possible attacks. Be very careful with input validation and only give the view the ability to do the things it really needs -- you don't want an external app to be able to delete entries in your database for example.

Django: Login from page outside django

Maybe it's a stupid question, but I'm trying to login to my django app using a form that is outside django. My guess is that I could send a POST request to /login, but that would fail because of the csrf token.
Maybe I'm missing some kind of theoretical background, but I would like to know what's the correct way to achieve this.
Background info:
The django authentication is working fine IF you use the django login forms. What I'd like to do is to use an external static html form (on an apache outside django), to post to django directly so when I redirect to my django server, I don't have to login.
CSRF exists to prevent exactly this. Although you no doubt have good intentions, there's no technical difference between this and a hacker trying to steal access to your site via a real CSRF attack.
Sounds like you need a single-signon service like CAS: http://code.google.com/p/django-cas/
(but it's possible overkill)