夜猫的个人小站

       继续码起来

关于作者

微博北极熊硬糖
北京海淀区

网站建设第七天注册用户邮件激活

标签

网站建设很早前就有了注册登录登出功能。只是没有添加邮箱认证环节。今天来添加上。

注册认证的步骤如下:
1.首先用户经过一般的注册程序(signup)。这时候,还没有激活。
2.网站后台发送一封带激活链接的邮件到注册用户邮箱。
3.用户登录邮箱点击链接,网站后台user_actice方法进行处理,将用户usr.is_active置为True.

后台django代码

首先在urls.py添加url

url(r'^signup$',base.signup,name='signup'),
url(r'^user_active/([a-zA-Z]+)$',base.user_active,name='user_active'),

base.py添加相关处理方法

    #----------------------------用户注册模块-----------------------------------------------------------------------------------------------
    @csrf_exempt
    def signup(request):
        user = request.user if request.user.is_authenticated() else None
        if  user:
            return HttpResponseRedirect(reverse('homepage'))
        state=""
        success=True
        response_data={}
        if request.method=='POST':
            username=request.POST.get('username','')
            email=request.POST.get('email','')
            password=request.POST.get('password','')
            repeat_password=request.POST.get('repeat_password','')

            #匹配邮箱格式
            if email=="":
                state+="邮箱不能为空,"
            pattern = re.compile(r'^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,3}){1,2})$')
            match = pattern.match(email)
            if not match:
                state+="邮箱格式不正确,"
            if User.objects.filter(email=email):
                state='邮箱已被注册,'
            #用户名
            if username=="":
                state+="用户名不能为空,"
            if User.objects.filter(username=username):
                state+='用户名已存在,'
            #验证密码
            if password=="" or repeat_password=="":
                state+="密码不能为空,"
            if len(password)<6:
                state+="密码不能少于6位,"
            if password!=repeat_password:
                state+='两次密码不一致'
            #state非空,说明注册失败
            if state!="":
                success=False
            #注册信息无误,数据库中建立新用户信息。
            else:
                new_user=User.objects.create_user(username=username,password=password,email=email)
                new_user.is_active=False#需要邮件激活
                new_user.save()
                new_my_user=MyUser(user=new_user,gender=request.POST.get('gender',''),signature=request.POST.get('signature',''),job=request.POST.get('job',''))
                new_my_user.save()
                state='注册成功,请去邮箱激活/'
                user=auth.authenticate(username=username,password=password)
                if user is not None:
                    auth.login(request,user)

            try:
                #发送激活邮件
                #不想用uuid模块生成唯一ID保存到数据库中,也不想用django-registration
                #安全级别要求不高,所以简单写个加密解密的方法来处理
                active_code=get_active_code(email)
                send_active_email(email,active_code)
            except Exception, e:
                state+=u'激活邮件发送失败。请稍后重试 '+e.message

            #判断requestuest请求是否是Ajax类型的,若是,则返回HttpResponse.
            if request.is_ajax():  
                response_data={'state':state,'success':success}
                return HttpResponse(json.dumps(response_data), content_type="application/json")

            #若不是ajax请求,与GET请求一起处理POST请求
        content={
        'state':state,
        'user':user,
        }           
        return render(request,'base/signup.html',content)

    def get_active_code(email):
        """get active code by email and current date"""
        key=9
        encry_str='%s|%s' % (email,time.strftime('%Y-%m-%d',time.localtime(time.time())))
        active_code=encrypt(key,encry_str)
        return active_code

    def send_active_email(email,active_code):
        """send the active email"""
        url='http://yefan.site%s' % (reverse('user_active',args=(active_code,)))

        subject=u'[yefan.site]激活您的帐号'
        message=u'''
            <h2>夜猫的个人小站(<a href='http://yefan.site/' target=_blank>yefan.site</a>)<h2><br />
            <p>欢迎注册,请点击下面链接进行激活操作(7天后过期):<a href="%s" target=_balnk>%s</a></p>
            ''' % (url,url)
        #get_from=['201421140020@mail.bnu.edu.cn']      
        send_to=[email]
        fail_silently=True  #发送异常不报错

        msg=EmailMultiAlternatives(subject=subject,body=message,to=send_to)
        msg.attach_alternative(message, "text/html")
        msg.send(fail_silently)
    #-------------------加密解密-------------------------------------------------------------
    def encrypt(key, s):   
        """encrypt string(key is a number)"""
        b = bytearray(str(s).encode('utf-8'))
        n = len(b) # 求出 b 的字节数   
        c = bytearray(n*2)   
        j = 0   
        for i in range(0, n):   
            b1 = b[i]
            b2 = b1 ^ key # b1 = b2^ key
            c1 = b2 % 16   
            c2 = b2 // 16 # b2 = c2*16 + c1   
            c1 = c1 + 65   
            c2 = c2 + 65 # c1,c2都是0~15之间的数,加上65就变成了A-P 的字符的编码   
            c[j] = c1 
            c[j+1] = c2
            j = j+2   
        return c.decode('utf-8').lower()

    def decrypt(key, s):
        """decrypt string(key is a number)"""
        c = bytearray(str(s).upper().encode('utf-8'))   
        n = len(c) # 计算 b 的字节数   
        if n % 2 != 0 :   
            return ""   
        n = n // 2   
        b = bytearray(n)   
        j = 0   
        for i in range(0, n):   
            c1 = c[j]   
            c2 = c[j+1]   
            j = j+2   
            c1 = c1 - 65   
            c2 = c2 - 65   
            b2 = c2*16 + c1   
            b1 = b2^ key   
            b[i]= b1   
        try:   
            return b.decode('utf-8')
        except:   
            return ""
    #------------------------------解密解密结束-----------------------------------------------------------
    #-------------------------邮件激活处理----------------------------------------------------------------
    def user_active(request,active_code):
        """user active from the code"""
        #加错误处理,避免出错。出错认为激活链接失效
        #解密激活链接
        key=9
        data={}
        try:
            decrypt_str=decrypt(key,active_code)
            decrypt_data=decrypt_str.split('|')
            email=decrypt_data[0]                                   #邮箱
            create_date=time.strptime(decrypt_data[1], "%Y-%m-%d")  #激活链接创建日期
            create_date=time.mktime(create_date)            #struct_time 转成浮点型的时间戳

            day=int((time.time()-create_date)/(24*60*60))     #得到日期差
            if day>7:
                raise Exception(u'激活链接过期')

            #激活
            user=User.objects.filter(email=email)
            if len(user)==0:
                raise Exception(u'激活链接无效')
            else:
                user=User.objects.get(email=email)

            if user.is_active:
                raise Exception(u'该帐号已激活过了')
            else:
                user.is_active=True
                user.save()
                # myuser=MyUser.objects.get(user=user)
                # myuser.active=""

            data['goto_page']=True
            data['message']=u'激活成功,欢迎访问!博主会陆续发表高质量的原创博文。'
        except IndexError, e:
            data['goto_page']=False
            data['message']=u'激活链接无效'
        except Exception, e:
            data['goto_page']=False
            data['message']=e
        finally:
            #激活成功就跳转到首页(message页面有自动跳转功能)
            data['goto_url']='/'
            data['goto_time']=3000

            return render_to_response('base/user_active.html',data)
    #------------------------------------邮件激活处理结束-----------------------------------------------------------------
    #---------------------------注册模块结束----------------------------------------------------------------------------------------------------------------------------

后端setting.py邮箱设置

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST= 'smtp.mail.bnu.edu.cn'
EMAIL_PORT= 25
EMAIL_HOST_USER = '201421140020@mail.bnu.edu.cn'  #Mailbox的名称
EMAIL_HOST_PASSWORD = '*****'  #Mailbox的密码 默认有SMTP服务
EMAIL_SUBJECT_PREFIX = '[yefan.site]' #邮件标题前缀,默认是'[django]'
EMAIL_USE_TLS = True
DEFAULT_FROM_EMAIL = SERVER_EMAIL = '201421140020@mail.bnu.edu.cn' #发件人的邮箱地址
前端js代码
<script type="text/javascript">

$(function(){
    $("#register").submit(function(event) {

        var $state=$(".state");
        var username=$("#id_username").val();
        var email=$("#id_email").val();
        var password=$("#id_password").val();
        var repeat_password=$("#id_repeat_password").val();
        //验证注册信息是否正确
        if (email==""){
            $state.text("邮箱不能为空!");
            return false;
        }
        if(!email.match(/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,3}){1,2})$/)){
            $state.text('请输入正确的邮箱格式!');
            return false;
        }
        if(username==""){
            $state.text("用户名不能为空!")
            return false;
        }
        if(password=="" || repeat_password==""){
            $state.text("密码为空!");
            return false;
        }
        if(password.length<6){
            $state.text("密码少于6位!");
            return false;
        }
        if(password!==repeat_password){
            $state.text("两次密码不一致!");
            return false;
        }

        //注册
        $state.text('注册中,请稍后...');

        $.ajax({
            type: "POST",
            data: $('#register').serialize(),
            url: "{% url 'signup' %}",
            cache: false,
            dataType: "json",
            success: function(json, textStatus){
                var is_success = json['success'];
                if(is_success){
                    $state.text('注册成功,请去邮箱激活...');

                    window.setTimeout(function(){ 
                        window.location.reload(); 
                    },3000);
                }else{
                    $state.text(json['state']);
                };
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                $state.text("注册出错,请重试 "+errorThrown);
            }
        });
        return false;

    });
})

</script>
signup.html部分,显示注册状态还有注册表单
<div style="text-align:center">
    <h3 class="state" style="color:#FFCC00">{{state}}</h3>
</div>

最新评论

发表评论
回到顶部