使用Django框架,实现一个简单的登录功能。
业务逻辑:
1、判断用户的请求方式。
2、如果是GET请求,显示注册页面。
3、如果是POST请求(表单提交,进行注册),判断注册的内容是否合理。
4、发送邮件,激活账号。
5、注册成功.
1、判断用户的请求方式
当用户访问到注册页面的时候,其实已经进行了一个GET请求,再点击注册的时候,又进行了一次POST请求。
可以使用浏览器的开发者工具中查看,
这是当用户访问注册页面的时候,进行的请求方式。
2、如果是GET请求,则展示注册页面
from django.shortcuts import render, redirect
from django.views.generic import View
class RegisterView(View):
"""注册"""
def get(self, request):
"""对应get请求方式,提供注册页面"""
return render(request, "register.html", )
3、如果是POST请求(表单提交,进行注册),判断注册的内容是否合理
下图是需要用户填写的信息
首先需要知道表单传递数据的方式
以控件的name属性的值为键,以value属性的值为值
在html页面中name属性分别为:user_name、pwd、email、allow
然后我们通过request.POST.get()的方式,获取用户输入的信息
class RegisterView(View):
"""注册"""
def get(self, request):
"""对应get请求方式,提供注册页面"""
return render(request, "register.html", )
def post(self, request):
"""对应post请求方式,接收处理用户的注册数据"""
# 接收传入的参数
user_name = request.POST.get("user_name")
password = request.POST.get("pwd")
email = request.POST.get("email")
allow = request.POST.get("allow")
获取用户输入的信息之后,在进行判断输入的数据是否合理
# 检验参数的正确性
if not all([user_name, password, email]):
# 重定向到注册页面
return redirect(reverse("users:register"))
if not re.match(r"^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$", email):
# 返回错误信息
return render(request, "register.html", {"errmsg": "邮箱格式不正确"})
if allow != "on":
return render(request, "register.html", {"errmsg": "请接收注册协议!"})
# 进行业务逻辑处理,将数据保存到数据库
将数据库保存到数据库中,在这里我们可以使用Django提供的用户认证系统
认证系统文档链接:
http://python.usyiyi.cn/documents/django_182/topics/auth/default.html
我们需要传入 用户名、邮箱、密码 三个参数 (遵循参数传入的顺序)
create_user() 还帮助我们对密码进行了加密,使用的是sha256进行加密并且加上盐值
try:
# django的AbstractUser基类提供的创建用户的方法
user = User.objects.create_user(user_name, email, password)
except db.IntegrityError:
# 如果用户名已存在,则抛出此异常信息
return render(request, "register.html", {"errmsg": "用户名已存在!"})
4、发送邮件,激活账号。
当用户所输入的信息正确且满足注册条件,将用户输入的信息保存到数据库中。
这个时候需要发送给用户一封邮件,提示用户激活账号。
如果用户还没有点击激活链接,则数据库中的激活状态为假
# 将用户的激活状态设置为假
user.is_active = False
user.save()
发送激活邮件的逻辑:
当用户点击激活链接的时候,把数据库中邮件激活状态的字典,修改为真
生成用户激活口令,并且激活链接具有有效期
假如我们需要给用户 id为1的用户激活,那么url路径 为 /users/active/1 这样我们就把用户的id暴露了,为了避免非法用户的恶意激活,我们需要对id值进行加密,而且激活链接具有 有效期,所以可以使用itsdangerous模块(需要安装 pip install itsdangerous)
itsdangerous模块 给一个特定的信息进行加密处理,与密码加密不同的是密码加密是不能反推明文来的,而itsdangerous模块进行序列化(加密)是可以反推出明文的。
并且可以给生成的字符串添加有效期。
关于itsdangerous的方法:http://itsdangerous.readthedocs.io/en/latest/
# 为用户生成激活口令
token = user.generate_active_token()
将这个方法放到model.py中
需要导入itsdanerous模块
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
class User(AbstractUser, BaseModel):
"""用户"""
class Meta:
db_table = "df_users"
def generate_active_token(self):
"""生成激活令牌"""
serializer = Serializer(settings.SECRET_KEY, 3600)
token = serializer.dumps({"confirm": self.id}) # 返回bytes类型
return token.decode()
其中settings.SECRET_KEY 为混淆字符串(django自带的)
class ActiveView(View):
"""激活"""
def get(self, request, token):
"""
:param request:
:param token: token是用户携带的口令,唯一标识用户
:return:
"""
# 解析口令token,获取用户身份
# 构建序列化器
s = Serializer(settings.SECRET_KEY)
try:
data = s.loads(token)
except SignatureExpired:
# 表示token过期
return HttpResponse("链接已过期!")
# 表示token未过期,
user_id = data.get("confirm")
# 查询用户的数据
try:
user = User.objects.get(id=user_id)
except User.DoesNotExist:
# 用户不存在
return HttpResponse("用户不存在!")
# 设置用户的激活状态
user.is_active = True
user.save()
# 返回处理结果
# return HttpResponse("进入到登录页面")
return redirect(reverse("users:login"))