注册 登陆 验证码

思路:

注册模块:

  • 邮箱格式
  • 邮箱是否存在
  • 邮箱规定时间内注册次数
  •   邮箱验证码验证

登陆:

  • 登陆验证码验证
  • 用户名与密码验证
  • 邮箱与密码验证

注销:

  • 清除session
from django.shortcuts import render,HttpResponse,redirect
import io
import json
import datetime
from chouti_test import models
from statics import check_code as CheckCode
from statics import commons
from django import forms

class StatusCodeEnum:

    Failed = 1000
    AuthFailed = 1001
    ArgsError = 1002
    Success = 2000
    FavorPlus = 2301
    FavorMinus = 2302


class BaseResponse:

    def __init__(self):
        self.status = False
        self.code = StatusCodeEnum.Success
        self.data = None
        self.summary = None
        self.message = {}

class SendMsgForm(forms.Form):
    email = forms.EmailField()

class RegisterForm(forms.Form):
    username = forms.CharField()
    email = forms.EmailField()
    password = forms.CharField()
    email_code = forms.CharField()

class LoginForm(forms.Form):
    user = forms.CharField()
    pwd = forms.CharField()
    code = forms.CharField()# 生成图片验证码
def check_code(request):

    stream = io.BytesIO() # 系统内一块内存
    # 创建随机字符 code
    # 创建一张图片格式的字符串,将随机字符串写到图片上
    img, code = CheckCode.create_validate_code() # 获取一张图片 一个验证码
    img.save(stream, "PNG")  # 在stream内存中保存img为PNG的图片
    # 将字符串形式的验证码放在Session中
    request.session["CheckCode"] = code  # 验证码保存到session
    return HttpResponse(stream.getvalue())  # 保存的stream中的图片发送到前端

# -----------------------三个判断 1.格式是否合法 2.邮箱是否存在 3.1hours内是否,超过10次注册------------------------

def send_msg(request):

    rep = BaseResponse()
    form = SendMsgForm(request.POST)
    """ ----------------------- 判断邮箱格式 --------------------------"""
    if form.is_valid():
        _value_dict = form.clean()  # 获取正确的信息
        email = _value_dict['email'] # 获取用户填的email
        has_exists_email = models.UserInfo.objects.filter(email=email).count()  # 对比email是否已经存在

# ----------------------------------判断邮箱是否已经存在------------------------------------

        if has_exists_email:  # 为真表示已被注册
            rep.summary = "此邮箱已经被注册"
            return HttpResponse(json.dumps(rep.__dict__))  # summary信息返回到前端

        current_date = datetime.datetime.now()
        code = commons.random_code()

        count = models.SendMsg.objects.filter(email=email).count()
        if not count: # 信息不存在,正常注册用户
            models.SendMsg.objects.create(code=code, email=email, ctime=current_date)
            rep.status = True
        else: # 信息不存在2次判断。判断是否在一个小时内注册超过10次
            limit_day = current_date - datetime.timedelta(hours=1)
            # 判断是否存在,输入的email,大于limit_day的时间(时间越大越靠近current_time,说明在1hours内),times大于9次
            times = models.SendMsg.objects.filter(email=email, ctime__gt=limit_day, times__gt=9).count()
# --------------------------------判断一个小时内的验证码发送的次数-------------------------------
            if times:
                rep.summary = "'已超最大次数(1小时后重试)'"
            else: # 1.时间小于limit_day  2.时间大于limit_day,times小于10次的
                # 时间小于limit_day
                unfreeze = models.SendMsg.objects.filter(email=email, ctime__lt=limit_day).count()
                if unfreeze:
                    models.SendMsg.objects.filter(email=email).update(times=0)
                from django.db.models import F
                models.SendMsg.objects.filter(email=email).update(code=code,
                                                                  ctime=current_date,
                                                                  times=F('times') + 1)
                rep.status = True

# -------------------------------------邮箱格式不正确----------------------------------------

    else:
        # error_dict = json.loads(form.errors.as_json())
        # rep.summary = error_dict['email'][0]['message']
        rep.summary = form.errors['email'][0]
    return HttpResponse(json.dumps(rep.__dict__))

# 对于form的输入格式验证,验证码时间验证

def register(request):
    """
    注册
    :param request:
    :return:
    """
    rep = BaseResponse()
    form = RegisterForm(request.POST)
    if form.is_valid():
        current_date = datetime.datetime.now()
        limit_day = current_date - datetime.timedelta(minutes=1)
        _value_dict = form.clean()

        is_valid_code = models.SendMsg.objects.filter(email=_value_dict['email'],
                                                      code=_value_dict['email_code'],
                                                      ctime__gt=limit_day).count()
        # 判断输入框
        if not is_valid_code:
            rep.message['email_code'] = '邮箱验证码不正确或过期'
            return HttpResponse(json.dumps(rep.__dict__))

        has_exists_email = models.UserInfo.objects.filter(email=_value_dict['email']).count()

        if has_exists_email:
            rep.message['email'] = '邮箱已经存在'
            return HttpResponse(json.dumps(rep.__dict__))

        has_exists_username = models.UserInfo.objects.filter(username=_value_dict['username']).count()
        if has_exists_username:
            rep.message['email'] = '用户名已经存在'
            return HttpResponse(json.dumps(rep.__dict__))

        _value_dict['ctime'] = current_date
        _value_dict.pop('email_code')
        # 当前用户的所有信息
        obj = models.UserInfo.objects.create(**_value_dict)

        user_info_dict = {'nid': obj.nid, 'email': obj.email, 'username': obj.username}

        models.SendMsg.objects.filter(email=_value_dict['email']).delete()

        request.session['is_login'] = True
        request.session['user_info'] = user_info_dict
        rep.status = True

    else:
        error_msg = form.errors.as_json()
        rep.message = json.loads(error_msg)
    return HttpResponse(json.dumps(rep.__dict__))

# ----------------------------------------登陆-------------------------------------
def login(request):
    """
    用户登陆
    :param request:
    :return:
    """
    rep = BaseResponse()
    form = LoginForm(request.POST)
    # 登陆验证码判断
    if form.is_valid():
        _value_dict = form.clean()
        if _value_dict['code'].lower() != request.session["CheckCode"].lower():
            rep.message = {'code': [{'message': '验证码错误'}]}
            return HttpResponse(json.dumps(rep.__dict__))
        # 验证码正确
        from django.db.models import Q

        con = Q()
        q1 = Q()
        q1.connector = 'AND'
        q1.children.append(('email', _value_dict['user']))
        q1.children.append(('password', _value_dict['pwd']))

        q2 = Q()
        q2.connector = 'AND'
        q2.children.append(('username', _value_dict['user']))
        q2.children.append(('password', _value_dict['pwd']))

        con.add(q1, 'OR')
        con.add(q2, 'OR')

        obj = models.UserInfo.objects.filter(con).first()
        if not obj:
            rep.message = {'user': [{'message': '用户名邮箱或密码错误'}]}
            return HttpResponse(json.dumps(rep.__dict__))

        request.session['is_login'] = True
        request.session['user_info'] = {'nid': obj.nid, 'email': obj.email, 'username': obj.username}
        rep.status = True
    else:
        error_msg = form.errors.as_json()
        rep.message = json.loads(error_msg)

    return HttpResponse(json.dumps(rep.__dict__))

# --------------------------------------------注销--------------------------------------------
def logout(request):
    """
    用户注销
    :param request:
    :return:
    """
    request.session.clear()
    return redirect('/index/')


---------------------------------------------models.py-------------------------------------

from django.db import models

class SendMsg(models.Model):

nid = models.AutoField(primary_key=True)
code = models.CharField(max_length=6)
email = models.CharField(max_length=32, db_index=True)
times = models.IntegerField(default=0)
ctime = models.DateTimeField()


class UserInfo(models.Model):
nid = models.AutoField(primary_key=True)
username = models.CharField(max_length=32, unique=True)
password = models.CharField(max_length=32)
email = models.CharField(max_length=32, unique=True)
ctime = models.DateTimeField()



 

 

一、安装依赖

CentOS

第一步:

1
yum install python-devel

 第二步: yum install freetype-devel libjpeg-devel libpng-devel

1
2
sudo yum install libtiff-devel libjpeg-devel libzip-devel freetype-devel \
    lcms2-devel libwebp-devel tcl-devel tk-devel

 第三步:RPM包安装PIL

1
2
3
下载安装:ftp://rpmfind.net/linux/atrpms/f20-x86_64/atrpms/stable/PIL-1.1.7-10.1.fc20.x86_64.rpm
 
更多版本:http://rpmfind.net/linux/rpm2html/search.php?query=PIL&submit=Search+...&system=&arch=

 

 

Windows

第一步:

1
2
3
4
5
6
7
8
下载安装pip
a. 下载地址:https://pypi.python.org/packages/source/p/pip/pip-7.1.2.tar.gz#md5=3823d2343d9f3aaab21cf9c917710196
b. 解压,进入目录
c. 安装,Python setup.py install
 
注:安装过程中可能依赖setuptools,安装过程如下:
下载文件:https://bootstrap.pypa.io/ez_setup.py
执行文件:Python ez_setup.py

 第二步:

1
pip install Pillow

  更多安装文档:http://pillow.readthedocs.org/en/latest/installation.html

二、下载源码执行

第一步:

  源码下载:https://files.cnblogs.com/files/wupeiqi/CheckCode.zip

第二步:

1
2
a. 解压
b. 运行:Python manage.py runserver 127.0.0.1:8000

 第三步:

  浏览器访问:http://127.0.0.1:8000/login/

三、原理

1、当用户访问 http://127.0.0.1:8000/login/ 时,Python自动生成一张图片输入到页面(即:验证码),并且将图片上的文字内容保存在 Session中(即:request.session["CheckCode"] = '验证码的文字内容')。

2、用户输入用户名密码,点击登陆时:

  • 首先,检查用户输入的 验证码 是否和Session中保存的验证码相同
  • 然后,检查用户输入的 用户名 和 密码是否正确

参考:https://www.cnblogs.com/wupeiqi/articles/4786251.html

 

posted @ 2019-10-14 14:29  Delta.Farce  阅读(254)  评论(0编辑  收藏  举报