平时找回密码用的最多的有2种机制,一是回答预设问题来重置,二是通过邮箱重置密码,想了一下第一种很容易实现,但用户注册时必须输入一大堆信息就很不好,第二种就很方便。
去看了下资料,邮箱重置密码机制的基本流程如下:
随机生成一字符串,将用户名、字符串、还有其他信息如过期时间存入一张表。
将含有这字符串的URL发送给用户邮箱,可以通过GET得到,验证一下,便可以允许用户输入新的密码了。
差不多就这个流程,其他的也有字符串本身就是用户名的MD5,或包含了更多信息,不过这样貌似不安全。
这里我用Django简单实现一下,没有错误输入等各种校验:
首先我建了一个class,专门用于储存找回密码信息:
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,提交一个请求:
#-*- 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
用户点击之后邮箱中的链接后,需要验证字符串:
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系统,还是很快的:
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')
差不多就这样,想不到忘记密码挺简单的一个功能实现起来还是比较麻烦的。
这是在做什么项目呀?
木有项目,玩玩Django而已...