129 Views

重置密码机制

平时找回密码用的最多的有2种机制,一是回答预设问题来重置,二是通过邮箱重置密码,想了一下第一种很容易实现,但用户注册时必须输入一大堆信息就很不好,第二种就很方便。

去看了下资料,邮箱重置密码机制的基本流程如下:

随机生成一字符串,将用户名、字符串、还有其他信息如过期时间存入一张表。
将含有这字符串的URL发送给用户邮箱,可以通过GET得到,验证一下,便可以允许用户输入新的密码了。
差不多就这个流程,其他的也有字符串本身就是用户名的MD5,或包含了更多信息,不过这样貌似不安全。

这里我用Django简单实现一下,没有错误输入等各种校验:

首先我建了一个class,专门用于储存找回密码信息:

from django.db import models

class FindPass(models.Model):
    username=models.CharField(max_length=20)
    activation_key=models.CharField(max_length=20)
    date=models.DateField(auto_now_add=True)

 

auto_now_add=True 每次更新时,系统会自动添加当前时间,这样就不用在程序里实现了。

当用户输入email,提交一个请求:

#!/usr/bin/python
#-*- coding: UTF-8 -*-

from django.contrib.auth.models import User
from django.shortcuts import render_to_response
from django.http import *
from findpass.models import FindPass
from utils.utils import *
from threading import Thread
from datetime import date
import sys
import random
import string
from time import strftime

def forget_password(request):
    email = request.POST['email']
    user = User.objects.get(email=email)
    if user:
        #生成一个字符串,长度为10到20
        activation_key=random_string(random.randint(10,20));
        #将用户名,字符串,当前时间存入数据库
        #检测是否存在
        findPasses = FindPass.objects.filter(username=user.username)
        if findPasses: #已经存在
            findPass = findPasses[0]
            findPass.activation_key=activation_key #更新key
        else:
            findPass=FindPass(username=user.username,activation_key=activation_key)
        findPass.save()
        #发送email
        th = Thread(target=send_html_mail,
                    args=('重置密码! 3天有效期!',
                        'click the url http://127.0.0.1:8080/accounts/resetpassowrd/'+activation_key,
                        [email]))
        th.start()
        #跳转页面
        return render_to_response('findpass/forget_password.html')
    else:
        #用户不存在的操作
        return render_to_response('404.html')

发送邮件用的是上次Django 邮件功能写的函数,非常方便。
random_string是我自己随便写的生成随机字符串的函数,很简单:

#生成随机字符串
def random_string(num):
    passward = ''
    seed = string.letters + string.digits
    for i in xrange(num):
        passward += seed[random.randrange(1,len(seed))]
    return passward

用户点击之后邮箱中的链接后,需要验证字符串:

def begin_reset_password(request,activation_key):
    findPasses=FindPass.objects.filter(activation_key=activation_key)
    if findPasses:
        findPass = findPasses[0]
        #比较时间 有效期 比如3天
        if int(date.today().strftime('%Y%m%d'))-int(findPass.date.strftime('%Y%m%d'))<3:
            #将User存入session或其他...
            user = User.objects.get(username=findPass.username)
            request.session['findpasser']=user
            #定向到重置密码解密
            return render_to_response('findpass/begin_reset_password.html',{'user':user})
    return render_to_response('404.html')

最后就可以重置密码了,用Django的User系统,还是很快的:

def reset_password(request):
    password = request.POST['password']
    user = request.session['findpasser']
    if user:
        user.set_password(password)
        user.save()
        #修改成功后的操作
        #删除记录
        FindPass.objects.get(username=user.username).delete()
        #删除session
        del request.session['findpasser']
        return render_to_response('findpass/reset_password_success.html')
    else:
        return render_to_response('404.html')

差不多就这样,想不到忘记密码挺简单的一个功能实现起来还是比较麻烦的。

无觅相关文章插件,快速提升流量

2 thoughts on “重置密码机制

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*


*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>