Django项目----基于Ajax和auth实现登录验证(加随机验证图片)

生成随机图片验证码:
def get_valid_img(request):
   # 方式1:采用本地已有图片,传回前端
    # with open("girl.jpg","rb") as f:
    #     data=f.read()
  # 方式2:生成随机背景颜色的图片
    # import PIL    

   # from PIL import Image # import random # def get_random_color(): # return (random.randint(0,255),random.randint(0,255),random.randint(0,255)) # image=Image.new("RGB",(250,40),get_random_color()) # # f=open("valid_code.png","wb") # image.save(f,"png") # f=open("valid_code.png","rb") # data=f.read() # f.close()
 # 方式3
    # import PIL
    #
    # from PIL import Image
    # import random
    # def get_random_color():
    #     return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
    #
    # image = Image.new("RGB", (250, 40), get_random_color())
    #
    # from io import BytesIO
    # f = BytesIO()
    # image.save(f, "png")
    # data = f.getvalue()
    # f.close()

    # 方式4:
    import PIL

    from PIL import Image
    from PIL import ImageDraw,ImageFont
    import random
   #定义随机颜色
def get_random_color(): return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))    #生成随机背景颜色的图片 image = Image.new("RGB", (250, 40), get_random_color()) # 生成五个随机字符 draw=ImageDraw.Draw(image) font=ImageFont.truetype("blog/static/font/kumo.ttf",size=32) temp=[] for i in range(5): random_num=str(random.randint(0,9)) random_low_alpha=chr(random.randint(97,122)) random_upper_alpha=chr(random.randint(65,90)) random_char=random.choice([random_num,random_low_alpha,random_upper_alpha]) draw.text((24+i*36,0),random_char,get_random_color(),font=font) # 保存随机字符 temp.append(random_char)  ===============================================================
    此处添加噪点噪线
 ===============================================================
# 在内存生成图片 from io import BytesIO f = BytesIO() image.save(f,"png") data = f.getvalue() f.close()   #将列表格式的随机字符整合成整个字符串 # ["a","2","2","s"] valid_str="".join(temp) # "a22s" print("valid_str",valid_str) request.session["valid_str"]=valid_str   #将生成的图片传回前端 return HttpResponse(data)

调用模块:

from django.shortcuts import render,HttpResponse,redirect

# Create your views here.

from django.contrib import auth
from django.http import JsonResponse

登录函数:

def login(request):

    if request.is_ajax():
        user=request.POST.get("user")
        pwd=request.POST.get("pwd")
        valid_code=request.POST.get("valid_code")
        res={"state":False,"msg":None}

        valid_str=request.session.get("valid_str")

        if valid_code.upper()==valid_str.upper():
            user=auth.authenticate(username=user,password=pwd)
            if user:
                res["state"]=True
                auth.login(request,user)

            else:
                res["msg"] = "userinfo or pwd error"
        else:
            res["msg"]="验证码错误"

        return JsonResponse(res)



    return render(request,"login.html")

噪点噪线(在内存中生成图片前):

# 噪点噪线
    width=250    #宽度为页面定义的验证图片宽
    height=40     #  高度为页面定义的验证图片高
    for i in range(100):
        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(400):
        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())

index函数:

def index(request):
    if not request.user.username:
        return redirect("/login/")


    return render(request,"index.html",)

login.html中的Ajax:

 

<script>
   // 登录验证
    $(".login_btn").on("click",function () {

        $.ajax({
            url:"",
            type:"post",
            data:{
                csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val(),
                user:$("#user").val(),
                pwd:$("#pwd").val(),
                valid_code:$("#valid_code").val(),
            },
            success:function (data) {
                console.log(data)
                if (data.state){
                    location.href="/index/"
                }
                else{
                     $(".error").text(data.msg)
                }

            }
        })

    })

    // 验证码刷新

    $("#valid_img").click(function () {
        $(this)[0].src+="?"
    });
</script>

 

 

基于Ajax和auth实现登录验证功能:

  1.基础登录功能

  2.登录验证功能

  3.随机图片验证

  4.登录检查(验证是否为登录状态)

from django.shortcuts import render,HttpResponse,redirect

# Create your views here.

from django.contrib import auth
from django.http import JsonResponse

def login(request):

    if request.is_ajax():
        user=request.POST.get("user")
        pwd=request.POST.get("pwd")
        valid_code=request.POST.get("valid_code")
        res={"state":False,"msg":None}

        valid_str=request.session.get("valid_str")

        if valid_code.upper()==valid_str.upper():
            user=auth.authenticate(username=user,password=pwd)
            if user:
                res["state"]=True
                auth.login(request,user)

            else:
                res["msg"] = "userinfo or pwd error"
        else:
            res["msg"]="验证码错误"

        return JsonResponse(res)



    return render(request,"login.html")

def get_valid_img(request):

    # 方式1:
    # with open("girl.jpg","rb") as f:
    #     data=f.read()


    # 方式2:
    # import PIL
    #
    # from PIL import Image
    # import random
    # def get_random_color():
    #     return (random.randint(0,255),random.randint(0,255),random.randint(0,255))
    # image=Image.new("RGB",(250,40),get_random_color())
    #
    # f=open("valid_code.png","wb")
    # image.save(f,"png")
    # f=open("valid_code.png","rb")
    # data=f.read()
    # f.close()

    # 方式3
    # import PIL
    #
    # from PIL import Image
    # import random
    # def get_random_color():
    #     return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
    #
    # image = Image.new("RGB", (250, 40), get_random_color())
    #
    # from io import BytesIO
    # f = BytesIO()
    # image.save(f, "png")
    # data = f.getvalue()
    # f.close()

    # 方式4:


    import PIL

    from PIL import Image
    from PIL import ImageDraw,ImageFont
    import random
    def get_random_color():
        return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))


    image = Image.new("RGB", (250, 40), get_random_color())

    # 生成五个随机字符
    draw=ImageDraw.Draw(image)
    font=ImageFont.truetype("blog/static/font/kumo.ttf",size=32)
    temp=[]
    for i in range(5):
        random_num=str(random.randint(0,9))
        random_low_alpha=chr(random.randint(97,122))
        random_upper_alpha=chr(random.randint(65,90))
        random_char=random.choice([random_num,random_low_alpha,random_upper_alpha])
        draw.text((24+i*36,0),random_char,get_random_color(),font=font)

        # 保存随机字符
        temp.append(random_char)

    # 噪点噪线
    # width=250
    # height=40
    # for i in range(100):
    #     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(400):
    #     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())

    # 在内存生成图片
    from io import BytesIO
    f = BytesIO()
    image.save(f,"png")
    data = f.getvalue()
    f.close()



    # ["a","2","2","s"]
    valid_str="".join(temp)  # "a22s"
    print("valid_str",valid_str)

    request.session["valid_str"]=valid_str



    return HttpResponse(data)


def index(request):
    if not request.user.username:
        return redirect("/login/")


    return render(request,"index.html",)
Views.py
import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'nu^-2=lia#m2l&0*ku9vke^a(dygqment=n^*^6t!f2_boxm$x'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog.apps.BlogConfig',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    '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',
]

ROOT_URLCONF = 'cnblog_s9.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR,  'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'cnblog_s9.wsgi.application'


# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 's9_blog',
        "USER": "root",
        "PASSWORD":"123456",
        "HOST":"127.0.0.1",
        "PORT":3306
    }
}


# Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


AUTH_USER_MODEL="blog.UserInfo"


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/

STATIC_URL = '/static/'
settings.py
from django.conf.urls import url
from django.contrib import admin


from blog import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/', views.login),
    url(r'^get_valid_img/', views.get_valid_img),
    url(r'^index/', views.index),
]
urls.py
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="/static/bs/css/bootstrap.css">
    <script src="/static/js/jquery-3.2.1.min.js"></script>
    <style>
        .container{
            margin-top: 100px;
        }
    </style>
</head>
<body>
<h3>hello {{ request.user.username }},{{ request.user.email }}</h3>
</body>
</html>
index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="/static/bs/css/bootstrap.css">
    <script src="/static/js/jquery-3.2.1.min.js"></script>
    <link rel="stylesheet" href="/static/css/login.css">
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <form action="">
                  <div class="form-group">
                    <label for="user">用户名</label>
                    <input type="text" class="form-control" id="user" placeholder="Username">
                  </div>

                  <div class="form-group">
                    <label for="pwd">密码</label>
                    <input type="password" class="form-control" id="pwd" placeholder="Password">
                  </div>

                  <div class="form-group">
                    <label for="pwd">验证码</label>

                     <div class="row">
                         <div class="col-md-6">
                             <input type="text" class="form-control" id="valid_code">
                         </div>
                         <div class="col-md-6">
                             <img id="valid_img" width="250" height="40" src="/get_valid_img" alt="">
                         </div>

                     </div>
                  </div>

                <input type="button" class="btn btn-default login_btn" value="提交"><span class="error" style="color: red;margin-left: 20px"></span>
            </form>

        </div>
    </div>
</div>

{% csrf_token %}
#将Ajax另写入login.js 文件,通过静态文件路径引用Ajax
<script src="/static/js/login.js"></script>

</body>
</html>
login.html
   // 登录验证
    $(".login_btn").on("click",function () {

        $.ajax({
            url:"",
            type:"post",
            data:{
                csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val(),
                user:$("#user").val(),
                pwd:$("#pwd").val(),
                valid_code:$("#valid_code").val(),
            },
            success:function (data) {
                console.log(data)
                if (data.state){
                    location.href="/index/"
                }
                else{
                     $(".error").text(data.msg)
                }

            }
        })

    })

    // 验证码刷新

    $("#valid_img").click(function () {
        $(this)[0].src+="?"
    });
login.js
posted @ 2018-04-14 21:16  TheLand  阅读(361)  评论(0)    收藏  举报