This example will show you how to add django authenticate function when you implement a django login example.
1. Install Third Party Library django-simple-captcha.
1.1 Precondition.
- Open terminal and run below pip command to install django-simple-captcha and Pillow.
pip install django-simple-captcha pip install Pillow
- Add captcha in Django project settings.py file INSTALLED_APPS section.
- Execute below python command in terminal.
python manager.py migrations python manage.py migrate
- Add captcha url in Django project’s urls.py file urlpatterns section like below.
# this is the url that generate captcha code and image. url(r'^captcha/', include('captcha.urls'))
2. Django Login Example Source Code.
2.1 Captcha Form Source Code.
Below source code will create a django login form. The form has three form fields: username, password, and a captcha field ( captcha code input box and captcha image ).
# Import django forms module. from django import forms # Import CaptchaField filed type. from captcha.fields import CaptchaField # The custom CaptchaForm class extends forms.Form class. class CaptchaForm(forms.Form): # Create form field username and password username = forms.CharField(max_length=100, label='username') password = forms.FloatField(max_value=100, label='password') # Create a CaptchaField object in the form to generate captcha code input box, as well as the captcha image. # If user input verification code is incorrect, then it will display the error message "Verification code is not correct, input again." captcha = CaptchaField(error_messages={"invalid": u"Verification code is not correct, input again."})
2.2 LoginView and CreateCaptchaCodeView Source Code.
LoginView will be invoked when user submit login data, CreateCaptchaCodeView will be invoked when client use ajax to request a new captcha code and image.
# The LoginView class extends django View class. class LoginView(View): # Process get request, when user access the LoginView with get method, then display login.html to client. def get(self, request): # Create an instance of CapatchaForm class. login_form = CaptchaForm() # Return login.html to client. return render(request, "login.html", locals()) # Process post request, when user submit username, password and captcha code to LoginView then this method will be invoked. def post(self, request): # Create a CaptchaForm object. login_form = CaptchaForm(request.POST) # Get user input captcha code. captcha_code = request.POST.get("code") # If the user input captcha equals the generated captcha code. if captcha_code.upper() == request.session['captcha_code'].upper(): # Get username and password value. username = request.POST.get("username", "") password = request.POST.get("password", "") # Direct user to login_success.html file. return render(request, "login_success.html") else: # If user captcha verify failed, then redirect user to login.html file again. return render(request, "login.html", {'msg': "Wrong captcha code"}) # Captcha generation view, invoke this view to generate the captcha image and code. class CreateCaptchaCodeView(View): # Process get request. def get(self, request): # Create the captcha code and image. You can see the create_captcha_code method source code at below. img_obj, code = create_captcha_code() # Save the created image in BytesIO stream object. stream = BytesIO() img_obj.save(stream, 'png') # Save the generated captcha code in session. request.session['captcha_code'] = code # Return the captcha image. return HttpResponse(stream.getvalue())
2.3 The create_captcha_code() Method Source Code.
This method will create the captcha verification code and image.
# Import random class. import random # Import captcha used image module and class from Pillow package. from PIL import Image, ImageDraw, ImageFont, ImageFilter # Lowercase letters, remove the i, l, o, and z that might interfere _letter_cases = "abcdefghjkmnpqrstuvwxy" # Uppercase letters. _upper_cases = _letter_cases.upper() # Numbers. _numbers = ''.join(map(str, range(0, 10))) # Create captcha code used letters and numbers. init_chars = ''.join((_letter_cases, _upper_cases, _numbers)) ''' @todo: The create_captcha_code method will generate the captcha code and image. @param size: Captcha image size(width, height),default value is(120, 30) @param chars: Allowed character set. @param img_type: Captcha image format, default is GIF, optional for GIF, JPEG, TIFF, PNG. @param mode: Captcha image mode, default is RGB @param bg_color: The background color, white is default color. @param fg_color: The foreground color, the CAPTCHA character color, default is blue #0000FF @param font_size: Captcha code font size. @param font_type: Captcha font, default to AE_ALARABIYA.TTF. @param length: Number of Captcha characters. @param draw_lines: Whether to draw interference lines. @param n_lines: The number range of interference lines, tuple value, default is (1, 2), only valid when draw_lines is True. @param draw_points: Whether to draw interference points. @param point_chance: The probability of interference point, range is [0, 100] @return: [0]: PIL Image instace @return: [1]: CAPTCHA code in image. ''' def create_captcha_code(size=(120, 30), chars=init_chars, img_type="GIF", mode="RGB", bg_color=(255, 255, 255), fg_color=(0, 0, 255), font_size=18, font_type="Monaco.ttf", length=4, draw_lines=True, n_line=(1, 2), draw_points=True, point_chance=2): # Get the cpatcha image width and height. width, height = size # Create captcha image object. img = Image.new(mode, size, bg_color) # Create the draw image object. draw = ImageDraw.Draw(img) # Generates a string of given length. def get_chars(): return random.sample(chars, length) # Draw interference line. def create_lines(): # Number of interference lines. line_num = random.randint(*n_line) for i in range(line_num): # Start point. begin = (random.randint(0, size[0]), random.randint(0, size[1])) # End point. end = (random.randint(0, size[0]), random.randint(0, size[1])) draw.line([begin, end], fill=(0, 0, 0)) # Draw interference point. def create_points(): # Limit size to [0, 100]. chance = min(100, max(0, int(point_chance))) for w in range(width): for h in range(height): tmp = random.randint(0, 100) if tmp > 100 - chance: draw.point((w, h), fill=(0, 0, 0)) # Draws a CAPTCHA character. def create_strs(): c_chars = get_chars() # Each character is separated by a space strs = ' %s ' % ' '.join(c_chars) font = ImageFont.truetype(font_type, font_size) font_width, font_height = font.getsize(strs) draw.text(((width - font_width) / 3, (height - font_height) / 3), strs, font=font, fill=fg_color) return ''.join(c_chars) if draw_lines: create_lines() if draw_points: create_points() strs = create_strs() # Figure twist parameters. params = [1 - float(random.randint(1, 2)) / 100, 0, 0, 0, 1 - float(random.randint(1, 10)) / 100, float(random.randint(1, 2)) / 500, 0.001, float(random.randint(1, 2)) / 500 ] # Create a twist image. img = img.transform(size, Image.PERSPECTIVE, params) # Filter, boundary enhancement (larger threshold). img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) return img, strs
2.4 Html File Source Code.
<form class="form-signin" action="{% url "login" %}" method="post"> <h2 class="form-signin-heading">Login</h2> <label for="recipient-name" class="control-label">Username:</label> <input type="text" class="form-control" name="username" placeholder="Username" required autofocus> <label for="recipient-name" class="control-label">Password:</label> <input type="password" class="form-control" name="password" placeholder="Password" required> <label for="recipient-name" class="control-label">Captcha:</label> {{ login_form.captcha }} <button class="btn btn-lg btn-primary btn-block" type="submit">Login</button> {% csrf_token %} </form>
<!DOCTYPE html> {% load staticfiles %} <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> #code{ cursor: pointer; } </style> </head> <body> <div> <form action="{% url "login" %}" method="post"> <div><input type="text" name="username"></div> <div><input type="password" name="password"></div> <div><input type="text" name="code"><img src="{% url "create_captcha_code" %}" id="code"></div> <div>{{ msg }}</div> <div><input type="submit" value="Submit"></div> {% csrf_token %} </form> </div> </body> <script src="{% static "js/jquery-3.2.1.js" %}"></script> <script> $("#code").click(function () { $(this)[0].src = $(this)[0].src + "?"; }) </script> </html>
2.5 JQuery Source Code For Verification Code Refresh.
<script> // Add css style to captcha image. $(function(){ $(".captcha").css({ // The captcha image cursor is a pointer. "cursor": "pointer" }); $("#id_captcha_1").addClass("form-control") }); // When the captcha image is clicked, use ajax to refresh the verification code. $(".captcha").click(function () { // The /captcha/refresh/ is the verification code refresh url. $.getJSON("/captcha/refresh/", function (result) { // Change the captcha image url to the server returned image url. $(".captcha").attr("src", result["image_url"]); // Set the captcha verification code to a hidden field. $("#id_captcha_0").val(result['key']) }); }); </script>