实现注册邮箱验证和登陆验证码

Django发送邮件

需要使用到模块
from django.core.mail import send_mail,send_mass_mail

SMTP为邮件服务器,每一种邮箱smtp服务器地址不一样,自行百度
如163邮箱为smtp.163.com

一、在settings中添加配置


TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',

        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        # 'DIRS': [],

        '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',
            ],
        },
    },
]

#邮件配置
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_USE_TLS = True #是否使用TLS安全传输协议(用于在两个通信应用程序之间提供保密性和数据完整性。
EMAIL_USE_SSL = False #是否使用SSL加密,qq企业邮箱要求使用
EMAIL_HOST = 'smtp.163.com' #发送邮件的邮箱 的 SMTP服务器,这里用了163邮箱
EMAIL_PORT = 25 #发件箱的SMTP服务器端口
EMAIL_HOST_USER = '######@163.com' #发送邮件的邮箱地址
EMAIL_HOST_PASSWORD = 'pwd'
DEFAULT_FROM_EMAIL = 'zjw <#####@163.com>'

STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]

# 如下选项,表示将session对象交给redis管理
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"

在中urls添加配置

from django.contrib import admin

from django.conf.urls import include, url

urlpatterns = [

    url('admin/', admin.site.urls),
    url(r'Voting_items/', include('news.urls',namespace='voting')),

]
    以上配置就可以实现使用#######@163.com邮箱发送邮件

二、如何发送

编写模板文件

from django.db import models
from django.contrib.auth.models import User
#Create your models here.

class MyUser(User):
        #继承Django自带的USer模型类并重写
    url = models.URLField(blank=True, null=True, default="http://www.baidu.com")
    class Meta():
        verbose_name = "用户"
        verbose_name_plural = verbose_name

去admin中注册
from django.contrib import admin
from .models import *
#Register your models here.

admin.site.register(MyUser)

生成迁移文件并在数据库创建表
python manage.py makemigrations
python manage.py migrate

编写路由

from django.conf.urls import url
from . import views

app_name= 'voting'

urlpatterns = [

    # 验证码
    url(r'^verify/$', views.verify, name='verify'),
    # 注册
    url(r'^regist/$',views.regist,name='regist'),
    # 发邮件
    url(r'^active/(.*?)/$',views.active,name='active'),

]

编写视图
视图函数如下

1、安装 itsdangerous
pip install itsdangerous
2、序列化
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer,SignatureExpired

#发邮件
from django.core.mail import send_mail, send_mass_mail, EmailMultiAlternatives
from django.conf import settings
import random,io

#引入序列化加密并且有效期信息
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer,SignatureExpired

from django.shortcuts import render
from django.http import HttpResponse
from .models import MyUser
def regist(request):

    if request.method == 'GET':
        return render(request, 'Voting_items/regist.html')
    if request.method == "POST":
        username = request.POST.get("username_regi")
        pwd = request.POST.get("password_regi")
        pwd2 = request.POST.get("password_regi_2")

        res = None
        try:
            MyUser.objects.get()
            users = MyUser.objects.get_by_natural_key(username=username)
            if username == str(users):
                res = "该用户已注册"
                return render(request, 'Voting_items/login.html', {"res": res})
        except Exception as q:
            print(q)

        if pwd != pwd2:
            res = "密码不一致"
            return render(request, 'Voting_items/login.html', {"res": res})
        else:

            res = "注册成功,请在2个小时内激活。"
            user = MyUser.objects.create_user(username= username, password=pwd, url = 'http://www.baidu.com')
            print(user.id,user.username,user.is_active)
            # 注册用户之后默认为非激活状态
            user.is_active = False
            user.save()

            # 为了防止非人为激活,需要将激活地址加密
            # 带有有效期的序列化
            # 1 得到序列化工具
            serutil = Serializer(settings.SECRET_KEY,expires_in=7200)
            # 2 使用工具对字典对象序列化
            result =  serutil.dumps({"userid": user.id }).decode("utf-8")
            # print(result, type(result))

            mail = EmailMultiAlternatives("点击激活用户","请点击:<a href = 'http://127.0.0.1:8000/Voting_items/active/%s/'>点击激活</a>"%(result,),settings.DEFAULT_FROM_EMAIL,['zjw505104341@163.com'])
            mail.content_subtype = "html"
            mail.send()

            return render(request, 'Voting_items/login.html', {"res": res})

#加密数据并存到serutive中

def active(request,info):
    serutil = Serializer(settings.SECRET_KEY,expires_in=7200)
    try:
        obj = serutil.loads(info)
        print(obj["userid"])
        id = obj["userid"]
        user = get_object_or_404(MyUser, pk=id)
        user.is_active = True
        user.save()
        return redirect(reverse('voting:login'), {"res": "激活成功。"})
    except SignatureExpired as e:
        return HttpResponse("过期了")

#验证码

def verify(request):
    # try:
    #with open('1.png', 'wb') as f:
    #return HttpResponse(f.readable())
    #except Exception as e:
    #print(e)
    #return HttpResponse("出错了")

    #每次请求验证码,需要使用pillow构造出图像,返回
    #定义变量,用于画面的背景色、宽、高
    bgcolor = (random.randrange(20, 100),
               random.randrange(20, 100),
               random.randrange(20, 100))
    width = 100
    heigth = 35
    #创建画面对象
    im = Image.new('RGB', (width, heigth), bgcolor)
    #创建画笔对象
    draw = ImageDraw.Draw(im)
    #调用画笔的point()函数绘制噪点
    for i in range(0, 100):
        # 随机取得位置
        xy = (random.randrange(0, width), random.randrange(0, heigth))
        #随机取得颜色
        fill = (random.randrange(0, 255), 255, random.randrange(0, 255))
        #填充
        draw.point(xy, fill=fill)
    #定义验证码的备选值
    str1 = 'ABCD123EFGHIJK456LMNOPQRS789TUVWXYZ0qwertyuiopasdfghjklzxcvbnm'
    #随机选取4个值作为验证码
    rand_str = ''
    for i in range(0, 4):
        rand_str += str1[random.randrange(0, len(str1))]
    print(rand_str)
    #构造字体对象
    font = ImageFont.truetype('cambriab.ttf', 23)
    fontcolor = (255, random.randrange(0, 255), random.randrange(0, 255))

    #绘制4个字
    draw.text((5, 2), rand_str[0], font=font, fill=fontcolor)
    draw.text((25, 2), rand_str[1], font=font, fill=fontcolor)
    draw.text((50, 2), rand_str[2], font=font, fill=fontcolor)
    draw.text((75, 2), rand_str[3], font=font, fill=fontcolor)

    #释放画笔
    del draw
    request.session['verifycode'] = rand_str
    f = io.BytesIO()
    im.save(f, 'png')
    #将内存中的图片数据返回给客户端,MIME类型为图片png
    return HttpResponse(f.getvalue(), 'image/png')

编写界面
我用到了模板继承 下面这是login界面

{% extends 'Base.html' %}
{% block title %}
登陆界面
{% endblock %}

{% block body %}

{% comment %}
<form action="{% url 'polls:login' %}" method="post">
    {% csrf_token %}
    {{lf}}
    <input type="submit" value="登录">

</form>

<form action="#" method="post">
    {% csrf_token %}
    {{rf}}
    <input type="submit" value="注册">
</form>
{% endcomment %}

<div class="container">

    <!-- Nav tabs -->
    <ul class="nav nav-tabs" role="tablist">
        <li role="presentation" class="active"><a href="#home" aria-controls="home" role="tab" data-toggle="tab">登陆</a>
        </li>
        <li role="presentation"><a href="#messages" aria-controls="messages" role="tab" data-toggle="tab">注册</a></li>
    </ul>

    <!-- Tab panes -->
    <div class="tab-content">
        <div role="tabpanel" class="tab-pane active" id="home">
            状态:{{ res }}
            <div id="info"></div>
            <br>

            <form action="{% url 'voting:login' %}" method="POST" id="select">
                {% csrf_token %}
                <h4>登陆页面</h4>

                <p>
                    <input name="account" id="username" autocomplete="off" type="text" placeholder="请输入账户/手机号">
                </p>
                <p>
                    <input name="pwd" type="password" placeholder="请输入密码">
                </p>
                <p>
                    <img id="Img" src="{% url 'voting:verify' %}" alt="验证码"  />
                    <a href="#" onclick="reImg();">看不清,换一张</a>
                </p>
                <p>
                    <input name="verify" type="text" placeholder="请输入验证码">
                </p>
                <p>
                    <button type="submit" class="btn btn-primary" id="vote">登陆</button>
                </p>
            </form>

        </div>

        <div role="tabpanel" class="tab-pane" id="messages">
            <p><a href="{% url 'voting:regist' %}" class="btn btn-info">注册</a></p>

        </div>

        <div role="tabpanel" class="tab-pane" id="settings">

        </div>
    </div>

</div>

<script>

    <!--验证码刷新-->
    function reImg(){
        var img = document.getElementById("Img");
        img.src = "{% url 'voting:verify' %}?rnd=" + Math.random();
    }

</script>

{% endblock %}

下面这是regist界面
{% extends 'Base.html' %}

{% block title %}
注册界面

{% endblock %}

{% block body %}

    <div class="container">
        状态:{{ res }}
        <br>

        <form action="{% url 'voting:regist' %}" method="POST" id="select">
            {% csrf_token %}
            <h3>注册页面</h3>

                <input type="text" class="form-control" name="username_regi" id="username_regi" placeholder="请输入用户名">

                <input type="password" class="form-control" name="password_regi" id="password_regi" placeholder="请输入密码">

                <input type="password" class="form-control" name="password_regi_2" id="password_regi_2" placeholder="请再次输入密码">

                <button type="submit" class="btn btn-default">注册</button>
        </form>

    </div>

{% endblock %}

下面这是Base界面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>
        {% block title %}
        基类
        {% endblock %}
    </title>

    {% load static %}
    <link rel="stylesheet" href="{% static 'js/lib/bootstrap-3.3.7-dist/css/bootstrap.css' %}">
    <script src="{% static 'js/lib/jQuery/jquery-1.12.4.min.js' %}"></script>
    <script src="{% static 'js/lib/bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
    <script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
</head>
<body>

{% block body %}

{% endblock %}

</body>
</html>

因为我用到了BootStrap插件,所以要引入

在项目的同级目录下创建文件夹
static文件夹  在下方创建js文件夹  然后创建lib文件夹    把BootStrap文件放进去  和 jQuery文件放进去

第一个参数为主题
第二个参数为正文
第三个参数为发件人
第四个参数为收件人列表
send_mass_mail为批量发邮件
第一个参数为元组类型
元组中每一个项目均为send_mail中四个参数

三、如何实现用户注册激活
1、用户注册时向数据库直接注册用户,并且设置is_active为false
并且向用户邮箱发送邮件
2、邮件内容怎么拼接
邮件内容为激活用户的路由 : Exp
<a href=’http://127.0.0.1:8000/polls/active/10/’&gt; 点击激活</a>
3、编写激活路由
在激活路由中提取参数
将参数所对应的用户 的is_active设置为True
然后重定向登录页面

四、如何机密并且设置有效期
1、安装 itsdangerous
pip install itsdangerous
2、序列化
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer,SignatureExpired

针对字典形式内容序列化
#1 得到序列化工具
serutil = Serializer(settings.SECRET_KEY)
#2 使用工具对字典对象序列化
result = serutil.dumps({"userid": user.id }).decode("utf-8")
3、反序列化
使用配置相同的序列化工具
serutil = Serializer(settings.SECRET_KEY)
#info 代表反序列化字符串
obj = serutil.loads(info)
print(obj["userid"])

转载于:https://blog.51cto.com/14354046/2400128

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Java实现登陆注册验证码的示例代码: 1. 登陆页面(login.jsp) ```html <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>登陆页面</title> </head> <body> <h2>登陆页面</h2> <form action="login" method="post"> 用户名:<input type="text" name="username"><br> 密码:<input type="password" name="password"><br> 验证码:<input type="text" name="verifyCode"><br> <img src="verifyCode" alt="验证码"><br> <input type="submit" value="登陆"> </form> </body> </html> ``` 2. 注册页面(register.jsp) ```html <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>注册页面</title> </head> <body> <h2>注册页面</h2> <form action="register" method="post"> 用户名:<input type="text" name="username"><br> 密码:<input type="password" name="password"><br> 确认密码:<input type="password" name="confirmPassword"><br> 邮箱:<input type="text" name="email"><br> 验证码:<input type="text" name="verifyCode"><br> <img src="verifyCode" alt="验证码"><br> <input type="submit" value="注册"> </form> </body> </html> ``` 3. 登陆注册请求处理(LoginServlet.java和RegisterServlet.java) ```java import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @WebServlet("/login") public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); String verifyCode = request.getParameter("verifyCode"); HttpSession session = request.getSession(); String savedVerifyCode = (String) session.getAttribute("verifyCode"); if (!verifyCode.equalsIgnoreCase(savedVerifyCode)) { response.getWriter().write("验证码错误"); return; } // TODO 验证用户名和密码是否正确 // 如果正确,将用户信息保存到session中,并跳转到首页 session.setAttribute("username", username); response.sendRedirect("index.jsp"); } } @WebServlet("/register") public class RegisterServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); String confirmPassword = request.getParameter("confirmPassword"); String email = request.getParameter("email"); String verifyCode = request.getParameter("verifyCode"); HttpSession session = request.getSession(); String savedVerifyCode = (String) session.getAttribute("verifyCode"); if (!verifyCode.equalsIgnoreCase(savedVerifyCode)) { response.getWriter().write("验证码错误"); return; } // TODO 验证用户名、密码和邮箱是否符合要求,并保存用户信息到数据库中 // 如果注册成功,将用户信息保存到session中,并跳转到首页 session.setAttribute("username", username); response.sendRedirect("index.jsp"); } } ``` 4. 生成验证码(VerifyCodeServlet.java) ```java import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.util.Random; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @WebServlet("/verifyCode") public class VerifyCodeServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 设置响应头信息 response.setContentType("image/jpeg"); response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); // 设置验证码图片的宽和高 int width = 80, height = 30; // 创建一个图像对象 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 获取图形上下文 Graphics g = image.getGraphics(); // 设置背景色 g.setColor(new Color(255, 255, 255)); g.fillRect(0, 0, width, height); // 设置字体 g.setFont(new Font("Arial", Font.BOLD, 18)); // 生成随机数 Random random = new Random(); String verifyCode = ""; for (int i = 0; i < 4; i++) { int r = random.nextInt(10); verifyCode += r; g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255))); g.drawString(String.valueOf(r), i * (width / 4), 20 + random.nextInt(10)); } // 将验证码保存到session中 HttpSession session = request.getSession(); session.setAttribute("verifyCode", verifyCode); // 绘制干扰线 for (int i = 0; i < 10; i++) { g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255))); g.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height)); } // 结束绘制 g.dispose(); // 输出图像到客户端 ImageIO.write(image, "JPEG", response.getOutputStream()); } } ``` 以上是Java实现登陆注册验证码的示例代码,仅供参考。实际应用中需要根据具体情况进行修改和完善。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值