Sending Emails with Django CSRF Protection

Today I wanna talk about some details on how to send an email using Django, along with some brief introduction towards CSRF protection in django.

Structure of today’s blog:
1. CSRF
2. Implementation of sending an email using django
3. Some insignificant trouble met these days

Part 1: CSRF Protection

The CSRF protection is called ‘cross site request forgery protection’, the graph below shows how Web B could gain information from Web A using User C’s license without letting User C know.[[1]]

CSRF Attacking Method

Django CSRF protection works by checking for a nonce in each POST request. This ensures that a malicious user cannot simply ‘reply’ a form POST to your Web site and have another logged in user unwittingly submit that form. The malicious user would have to know the nonce, which is user specific (using a cookie). [[2]]

Part 2: Implementation

This part has 2 implementations, one with global setting CSRF closed, contrast to the other one with CSRF protection.

I). Without CSRF protection[[3]]:

a). Disable the CSRF module globally

#settings.py

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    ***# Annotate the order below***
    ***#'django.middleware.csrf.CsrfViewMiddleware',***
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
)

b). Implement sending email

#settings.py

EMAIL_HOST='smtp.sina.com'
EMAIL_PORT=25
EMAIL_HOST_USER='YOUR_EMAIL_ADDRESS'
EMAIL_HOST_PASSWORD='YOUR_PASSWORD'
EMAIL_SUBJECT_PREFIX=u'django'
EMAIL_USE_TLS=True

#views.py

def setEmail(request):
    if request.method=='POST':
        send_mail('subject', 'this is a msg of email', 'EMAIL_ADDRESS', ['EMAIL_ADDRESS'])
        return HttpResponse(u'Successfully sent')
    return render_to_response('contact_form.html')      

#urls.py

#Add this in urlpatterns
url(r'^setEmail/$', setEmail)

II). With CRSF protection[[4]]:

Flows:

a). The CSRF middleware is activated by default in the MIDDLEWARE_CLASSES setting, if you wanna override that setting, please do remember that ‘django.middleware.csrf.CsrfViewMiddleware’ should always come before any view middleware that assume that CSRF attacks have been dealt with. And if you disabled it like me ahead, you should have use csrf_protect() on particular views you wanna protect, and this is not recommended.

b). In any template that uses a POST form, use the csrf_token tag inside the ‘form’ tag, e.g.:

<form action="" method='post'>{% csrf_token %}

c). In the corresponding view functions, ensure that the ‘django.template.context_processors.csrf’ context processor is being used. Usually, this can be done in one of two ways:

c.1) Use RequestContext, which always uses ‘django.template.context_processor.csrf’ (no matter what template context processor are configured in the TEMPLATES settings).

c.2) Manually import and use the processor to generate the CSRF token and add it to the template context. e.g.:

from django.template.context_processors import csrf

def my_view(request):
    c={}
    c.update(csrf(request))
    #...view code here
    return render_to_response('a_template.html', c)

Mine is here:

#views.py

from django.template.context_processors import csrf

def contact(request):
    if request.method=='POST':
        form=ContactForm(request.POST)
        if form.is_valid():
            c={}
            c.update(csrf(request))
            cd=form.cleaned_data
            send_mail(
                cd['subject'],
                cd['message'],
                cd.get('email', 'EMAIL_ADDRESS'),
                ['EMAIL_ADDRESS'],
            )

            return render_to_response('contact_form.html', locals(), context_instance=RequestContext(request))
            #return HttpResponseRedirect('/contact/thanks/')
    else:
        form=ContactForm()
        c={}
        c.update(csrf(request))
    return render_to_response('contact_form.html', locals(), context_instance=RequestContext(request))

Finally, we can send emails.

Part 3: Some insignificant problems I met

Today I load django on my new ubuntu PC and confronted a problem when I create my first project. I use ‘pip’ to install django without using ‘sudo’, that is, I install django without authority of the root user. Defaultly, django file should be installed to the file under where the file python is. However, without authority, I pip the django into another dictionary and I just could not find it.
In fact, I should have used instruction ‘pip show django’ to find out its location. With the authority of the super user, it works out well.

Another problem lays in MySQL database. First, when I enter into mysql from shell I type in ‘show databases’ contrasting to the correct syntax ‘show databases;’, I then realize my fault and sequently type in the correct instruction. However, this could not run successfully. I must type in the right order the first time, it’s wired. Because of my recent focus on python, I always forget to add ‘;’ in mysql. More instruction could be seen at [[5]].

Yet I still meet another trouble. I wanna link to mysql from django, but whenever I type in ‘python manage.py shell’, it always throw an ”’django.core.exceptions.ImproperlyConfigured: You must define a ‘default’ database”’, I have the correct setting.py. Finally, it is because I use this -> ”’blablabla”’ to comment or we say to annotate while django does not take it as an annotation. I should have used ‘#’ to comment orders. ==.

References:
[1] http://www.wpython.com/361.html
[2] https://docs.djangoproject.com/en/1.8/topics/security/
[3] http://www.cnblogs.com/BeginMan/p/3443158.html
[4] https://docs.djangoproject.com/en/1.8/ref/csrf/
[5] http://blog.knowsky.com/186050.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值