03 登录认证

编辑本博客

知识点:

  • JsonResponse()Django直接序列化,不用json.dumps()
  • request.session['valid_code]=valid_code保存验证码
  • 一次请求伴随多次请求,如静态文件请求和验证码请求
  • PIL模块掌握
  • session存储验证码
  • 验证码刷新

登录界面html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
    <link rel="stylesheet" href="/static/css/bootstrap.css">
</head>
<body>
<h3 class="text-center">登录页面</h3>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-lg-offset-3">
                <form>
                    <div class="form-group">
                        <label for="user">用户名:</label>
                        <input type="text" id="user" class="form-control">
                    </div>
                    <div class="form-group">
                        <label for="pwd">密码:</label>
                        <input type="password" id="pwd" class="form-control">
                    </div>
                    <div style="margin-top: 10px">
                        <input type="button" value="登录" class="btn btn-default login_btn pull-right">
                    </div>

                </form>
            </div>
        </div>
    </div>
</body>
</html>
View Code

生成验证码

验证码的前端实现

<div class="form-group">
    <label for="">验证码:</label>
    <div class="row">
        <div class="col-md-6">
            <input type="text" class="form-control">
        </div>
        <div class="col-md-6">
            <img src="/get_validCode_img/" width="250px" height="35px">
        </div>
    </div>
</div>
View Code

后端实现

返回图片方式一,读取现有图片:

def get_validCode_img(request):
    #方式一
    with open('img.png','rb') as f:
        data=f.read()
    return HttpResponse(data)
View Code

 返回图片方式二,动态生成图片,存储在磁盘中:

def get_validCode_img(request):
    # 方式二
    from PIL import Image
    import random
    def get_random_color():
        return (random.randint(0,255),random.randint(0,255),random.randint(0,255))
    img=Image.new("RGB",(250,35),color=get_random_color())
    with open('validCode.png',"wb") as f:
        img.save(f,'png')
    with open('validCode.png','rb') as f:
        data=f.read()
    return HttpResponse(data)
View Code

 返回图片方式三,动态生成图片,图片存储在内存中:

def get_validCode_img(request):
    # 方式三
    from PIL import Image
    from io import BytesIO
    import random
    def get_random_color():
        return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
    img = Image.new("RGB", (250, 35), color=get_random_color())
    f=BytesIO()
    img.save(f,'png')
    data=f.getvalue()
    return HttpResponse(data)
View Code

动态生成图片内容

def get_validCode_img(request):
    from PIL import Image,ImageDraw,ImageFont
    from io import BytesIO
    import random
    def get_random_color():
        return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
    img = Image.new("RGB", (250, 35), color=get_random_color())
    draw=ImageDraw.Draw(img)
    font=ImageFont.truetype("static/font/JOKERMAN.ttf",size=20)
    for i in range(5):
        random_num=str(random.randint(0,9))
        random_low_alpha=chr(random.randint(95,122))
        random_upper_alpha=chr(random.randint(65,90))
        char=random.choice([random_low_alpha,random_num,random_upper_alpha])
        draw.text((i*40+30,3),char,get_random_color(),font=font)
    f = BytesIO()
    img.save(f, 'png')
    data = f.getvalue()
    return HttpResponse(data)
View Code

图片添加噪点

def get_validCode_img(request):
    from PIL import Image,ImageDraw,ImageFont
    from io import BytesIO
    import random
    def get_random_color():
        return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
    img = Image.new("RGB", (250, 35), color=get_random_color())
    draw=ImageDraw.Draw(img)
    font=ImageFont.truetype("static/font/JOKERMAN.ttf",size=20)
    for i in range(5):
        random_num=str(random.randint(0,9))
        random_low_alpha=chr(random.randint(95,122))
        random_upper_alpha=chr(random.randint(65,90))
        char=random.choice([random_low_alpha,random_num,random_upper_alpha])
        draw.text((i*40+30,3),char,get_random_color(),font=font)

    width=250
    height=35
    for i in range(10):
        x1=random.randint(0,width)
        x2=random.randint(0,width)
        y1=random.randint(0,height)
        y2=random.randint(0,height)
        draw.line((x1,y1,x2,y2),fill=get_random_color())
    for i in range(50):
        draw.point([random.randint(0,width),random.randint(0,height)],fill=get_random_color())
        x = random.randint(0, width)
        y = random.randint(0, height)
        draw.arc((x,y,x+4,y+4),0,90,fill=get_random_color())
    f = BytesIO()
    img.save(f, 'png')
    data = f.getvalue()
    return HttpResponse(data)
View Code

给验证码src添加一个“?”实现刷新验证码

<script>
    $("#valid_code_img").click(function () {
        $(this)[0].src+='?'
    })
</script>
View Code

保存验证码字符串

 通过会话跟踪技术保存验证码

#会话跟踪技术保存valid_vode_str
request.session['valid_code_str']=valid_code_str
def get_validCode_img(request):
    from PIL import Image,ImageDraw,ImageFont
    from io import BytesIO
    import random
    def get_random_color():
        return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
    img = Image.new("RGB", (250, 35), color=get_random_color())
    draw=ImageDraw.Draw(img)
    font=ImageFont.truetype("static/font/JOKERMAN.ttf",size=20)
    valid_code_str=""#保存验证码
    for i in range(5):
        random_num=str(random.randint(0,9))
        random_low_alpha=chr(random.randint(95,122))
        random_upper_alpha=chr(random.randint(65,90))
        char=random.choice([random_low_alpha,random_num,random_upper_alpha])
        valid_code_str+=char
        draw.text((i*40+30,3),char,get_random_color(),font=font)
    #会话跟踪技术保存valid_vode_str
    request.session['valid_code_str']=valid_code_str
    f = BytesIO()
    img.save(f, 'png')
    data = f.getvalue()
    return HttpResponse(data)
View Code

对验证码生成函数解耦

新建一个utils工具包,并创建calidCode模块,在模块中创建get_valid_code_img方法

from PIL import Image, ImageDraw, ImageFont
from io import BytesIO
import random


def get_random_color():
    return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
def get_valid_code_img(request):
    img = Image.new("RGB", (250, 35), color=get_random_color())
    draw = ImageDraw.Draw(img)
    font = ImageFont.truetype("static/font/STSONG.ttf", size=20)
    valid_code_str = ""  # 保存验证码
    for i in range(5):
        random_num = str(random.randint(0, 9))
        random_low_alpha = chr(random.randint(95, 122))
        random_upper_alpha = chr(random.randint(65, 90))
        char = random.choice([random_low_alpha, random_num, random_upper_alpha])
        valid_code_str += char
        draw.text((i * 40 + 30, 3), char, (0, 0, 0), font=font)
    # 会话跟踪技术保存valid_vode_str
    request.session['valid_code_str'] = valid_code_str
    # 添加噪点
    # width=250
    # height=35
    # for i in range(3):
    #     x1=random.randint(0,width)
    #     x2=random.randint(0,width)
    #     y1=random.randint(0,height)
    #     y2=random.randint(0,height)
    #     draw.line((x1,y1,x2,y2),fill=get_random_color())
    # for i in range(10):
    #     draw.point([random.randint(0,width),random.randint(0,height)],fill=get_random_color())
    #     x = random.randint(0, width)
    #     y = random.randint(0, height)
    #     draw.arc((x,y,x+4,y+4),0,90,fill=get_random_color())
    f = BytesIO()
    img.save(f, 'png')
    data = f.getvalue()
    return data
View Code

在view中导入相关函数

滑动验证

所需组件

验证用户名和密码

from django.contrib import auth

html页面中通过ajax技术请求,验证成功跳转到主页,验证错误显示错误信息

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
    <link rel="stylesheet" href="/static/css/bootstrap.css">
</head>
<body>
<h3 class="text-center">登录页面</h3>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-lg-offset-3">
                <form>
                    {% csrf_token %}
                    <div class="form-group">
                        <label for="user">用户名:</label>
                        <input type="text" id="user" class="form-control">
                    </div>
                    <div class="form-group">
                        <label for="pwd">密码:</label>
                        <input type="password" id="pwd" class="form-control">
                    </div>
                    <div class="form-group">
                        <label for="">验证码:</label>
                        <div class="row">
                            <div class="col-md-6">
                                <input type="text" id="valid" class="form-control">
                            </div>
                            <div class="col-md-6">
                                <img src="/get_validCode_img/" width="250px" height="35px" id="valid_code_img">
                            </div>
                        </div>
                    </div>
                    <div style="margin-top: 10px">
                        <span class="has-error"></span>
                        <input type="button" value="登录" id="login_btn" class="btn btn-default login_btn pull-right">
                    </div>

                </form>
            </div>
        </div>
    </div>
</body>
<script src="/static/js/jquery-3.3.1.js"></script>
<script>
    //刷新验证码
    $("#valid_code_img").click(function () {
        $(this)[0].src+='?'
    });
    //登录验证
    $("#login_btn").click(function () {
        $.ajax({
            url:"",
            type:'POST',
            data:{
                user:$("#user").val(),
                pwd:$("#pwd").val(),
                valid_code:$("#valid").val(),
                csrfmiddlewaretoken:$("input[name='csrfmiddlewaretoken']").val()
            },
            success:function (data) {
                if(data.user){
                    location.href="/index/"
                }
                else{
                    $(".has-error").text(data.msg).css({'color':'red'})
                }
            }
        })
    })
</script>
</html>
View Code

view视图中需导入的模块

from django.shortcuts import render,HttpResponse,redirect
from django.http import JsonResponse
from django.contrib import auth
from django.contrib.auth.decorators import login_required
View Code

view视图中对用户提交的数据进行验证,验证成功后通过auth.login()来注册用户

def login(request):
    if request.method=="POST":
        response={'user':None,'msg':None}
        user=request.POST.get('user')
        pwd=request.POST.get('pwd')
        valid_code=request.POST.get('valid_code')
        valid_code_str=request.session.get('valid_code_str')
        if valid_code_str.upper()==valid_code.upper():
            user=auth.authenticate(username=user,password=pwd)
            if user:
                auth.login(request,user)#注册session用户,request.user=当前登录用户
                response['user']=user.username
            else:
                response['msg']='username or password error!'
        else:
            response['msg']="valid code error!"
        return JsonResponse(response)
    return render(request,'login.html')
View Code
posted @ 2018-07-24 08:49  丫丫625202  阅读(155)  评论(0编辑  收藏  举报