Authentication on Shared Host using FastCGI
In this chapter, we will implement authentication such as login, logout, invalid login etc. on a shared host (justhost) using FastCGI.
We need put two files in ~/www/dj directory:
# pwd /home2/bogotob1/public_html/dj # ls ./ ../ djangoproject.fcgi* .htaccess
djangoproject.fcgi:
#! /home2/bogotob1/python/bin/python import sys, os sys.path.insert(0, "/home2/bogotob1/python") sys.path.insert(13, "/home2/bogotob1/djangoproject") os.environ['DJANGO_SETTINGS_MODULE'] = 'djangoproject.settings' from django.core.servers.fastcgi import runfastcgi runfastcgi(method="threaded", daemonize="false")
.htaccess:
# django AddHandler fcgid-script .fcgi RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ djangoproject.fcgi/$1 [QSA,L]
Django provides default authentication via setting.py. We need to check two things (highlighted lines below) are enabled in that file:
INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'djangoapp', ) MIDDLEWARE_CLASSES = ( 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', )
Authentication related urls are defined in urls.py:
from django.conf.urls import patterns, include, url from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', # Examples: url(r'^$', 'djangoapp.views.home', name='home'), # url(r'^blog/', include('blog.urls')), url(r'^admin/', include(admin.site.urls)), # user authentication urls url(r'^accounts/login/$', 'djangoapp.views.login'), url(r'^accounts/auth/$', 'djangoapp.views.auth_view'), url(r'^accounts/login/accounts/auth/$', 'djangoapp.views.auth_view'), url(r'^accounts/logout/$', 'djangoapp.views.logout'), url(r'^accounts/loggedin/$', 'djangoapp.views.loggedin'), url(r'^accounts/invalid/$', 'djangoapp.views.invalid_login'), )
The views for authentication are defined in views.py:
from django.shortcuts import render_to_response from django.http import HttpResponseRedirect from django.contrib import auth from django.core.context_processors import csrf def home(request): return render_to_response('home.html', {'Testing' : 'Django Template Inheritance ', 'HelloHello' : 'Hello World - Django'}) def login(request): c = {} c.update(csrf(request)) return render_to_response('login.html', c) def auth_view(request): username = request.POST.get('username', '') password = request.POST.get('password', '') user = auth.authenticate(username=username, password=password) if user is not None: auth.login(request, user) return HttpResponseRedirect('/dj/accounts/loggedin') else: return HttpResponseRedirect('/dj/accounts/invalid') def logout(request): auth.logout(request) return render_to_response('logout.html') def loggedin(request): return render_to_response('loggedin.html', {'full_name': request.user.username}) def invalid_login(request): return render_to_response('invalid_login.html')
The html files shown in the picture above are:
templates/base.html:
<html> <head> <title>This is Hello World app!</title> </head> <body> <h1>Welcome to Django at bogotobogo.com</h1> {% block content %} {% endblock %} </body> </html>
templates/home.html:
{% extends "base.html" %} {% block content %} {{ Testing }} {{ HelloHello }} {% endblock %}
templates/login.html:
{% extends "base.html" %} {% block content %} {% if form.errors %} <p class="error">Sorry, not a valid username or password</p> {% endif %} <form action="/dj/accounts/auth/" method="post">{% csrf_token %} <label for="username">User name:</label> <input type="text" name="username" value="" id="username"> <label for="password">Password:</label> <input type="password" name="password" value="" id="password"> <input type="submit" value="login" /> </form> {% endblock %}
templates/loggedin.html:
{% extends "base.html" %} {% block content %} <h2>Hi {{full_name}} you are now logged in!</h2> <p>Click <a href="/dj/accounts/logout/">here</a> to logout.</p> {% endblock %}
templates/invalid_login.html:
{% extends "base.html" %} {% block content %} <h2>Your login is invalid!</h2> <p>Click <a href="/dj/accounts/login/">here</a> to login again.</p> {% endblock %}
templates/logout.html:
{% extends "base.html" %} {% block content %} <h2>You are logged out.</h2> <p>Click <a href="/dj/accounts/login/">here</a> to login again.</p> {% endblock %}
DB is defined in settings.py:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'bogotob1_djforum', 'USER': 'bogotob1', 'PASSWORD': 'password', 'HOST': 'localhost', # Or an IP Address that your DB is hosted on 'PORT': '3306', } }
We need to run syncdb:
python manage.py syncdb Creating tables ... Installing custom SQL ... Installing indexes ... Installed 0 object(s) from 0 fixture(s)
Since I've done it earlier, the output shows "Installed 0 object(s) from 0 fixture(s)". It may be different depend on the status of sync.
Login:
Successful loggin:
Logout:
Invalid login:
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization