写点什么

Python Web 菜谱项目再次前进一步,从应用层了解内置用户认证系统

发布于: 2021 年 08 月 18 日

橡皮擦,一个逗趣的互联网高级网虫。新的系列,让我们一起进入 Django 世界。


九、Django 用户认证与鉴权,注册登录逻辑实现,注销功能

9.1 Django 用户认证

之前的博客中已经对 Django 中用户身份认证系统有过初步了解,在这套用户身份认证系统中可以处理用户账户,用户组,用户权限,Cookie 想干问题,主要解决了 Web 系统中两个问题,分别是认证、鉴权。


认证解决的是否可以登录问题,鉴权解决用户登录之后可以做什么的问题。


在 Django 中内置了一个 User 模型,字段如下:


  • username:用户名,150 字符以内;

  • firstname:名字字段,30 字符以内,国内不常用;

  • lastname:姓字段,150 字符以内,国内不常用;

  • email:邮箱字段;

  • password:密码字段;

  • groups:用户组字段;

  • is_staff:是否是管理员,布尔类型;

  • is_active:用户是否可用,布尔类型;

  • is_superuser:超级管理员字段;

  • last_login:用户最后登录时间;

  • date_joined:用户账号创建时间。

9.1.1 创建用户

在 Django 的用户系统中,因为涉及密码管理,不能直接通过 User 类的构造函数创建 User 对象并调用 save 方法创建用户。一般使用 User 模型的 Manage 提供的 create_user 方法,传入参数实现对用户的创建。


# 第一个参数是用户名,第二个参数是邮箱,第三个参数是密码user = User.objects.create_user("xiangpica","xxxxxxxxx@88.com","admin_123")
复制代码


修改密码,使用下述方法。


user = User.objects.get(username="xiangpica")user.set_password("C@xiang")user.save()
复制代码


这个是普通用户的创建方式,如果希望创建一个超级用户,使用 createsuperuser 命令即可,可参考下述步骤。


> python manage.py createsuperuserUsername (leave blank to use 'administrator'): xiangEmail address: w@163.comPassword:Password (again):This password is too short. It must contain at least 8 characters.This password is too common.Bypass password validation and create user anyway? [y/N]: ySuperuser created successfully.
复制代码

9.2 注册登录逻辑实现

接下来就要实现上文未完成的逻辑部分想干代码了,这里需要补充的知识也比较抽象,第一个就是在一个网站中,如果用户登录成功,Django 会通过 cookie 信息记录用户的登录状态,并且可以通过 cookie 中的信息查找到 session(会话)和用户信息,依旧是先实现,再补充逻辑知识点。

9.2.1 注册用户入库

在正式注册前,先打开 sqlite3 看一下里面的数据,这里橡皮擦使用的软件是 https://sqlitebrowser.org/dl/ 。直接打开项目目录的 db.sqlite3 文件即可查阅。



修改 views.py 文件中内部逻辑,修改 register.html 页面逻辑,代码如下:views.py


# 投入记住先导入该模块from django.contrib.auth.models import Userdef register(request):    if request.user.is_authenticated:        return HttpResponseRedirect(reverse("default"))
# 用户注册状态信息 state = None # 当用户提交注册信息 if request.method == "POST": username = request.POST.get("username", "") password = request.POST.get("password", "") email = request.POST.get("email", "") # 判断用户名是否存在 if User.objects.filter(username=username): state = "user_exist"
else: n_user = User.objects.create_user(username=username, password=password, email=email) # 保存注册信息到数据库 n_user.save() state = "success" # 表示注册成功
context = { "active_menu": 'default', "user": None, "state": state } return render(request, "menuapp/register.html", context)
复制代码


register.html


{% block content %}<div class="container">  <h2 class="form-signup-heading">注册</h2>  <div class="well">    {% if state == "user_exist" %}    <h2 class="text-warning">用户已经被注册!</h2>    {% endif %} {% if state == "success" %}    <h2 class="text-success">注册成功!</h2>    {% endif %}  </div></div>
复制代码


重新运行菜谱程序,注册用户,第一次成功,第二次在注册,提示用户已经被注册,此时注册界面完成最小可用功能。



查询数据库数据,发现已经入库。


9.2.2 用户登录完善

模仿注册相关实现,对登录逻辑进行补充,重点修改 views.py 文件与 login.html 文件:


login.html


{% block content %}<div class="container">  <h2 class="form-signup-heading">登录</h2>  {% if state == "login_error" %}  <h2 class="text-warning">用户名或者密码错误!</h2>  {% endif %}</div>
复制代码


views.py


# 提前导入 auth 模块from django.contrib import auth# 登录视图def login(request):    if request.user.is_authenticated:        return HttpResponseRedirect(reverse("default"))    # 登录状态信息    state = None    if request.method == "POST":        username = request.POST.get("username", "")        password = request.POST.get("password", "")        # 登录验证        user = auth.authenticate(username=username, password=password)        if user is not None:            auth.login(request, user)            return HttpResponseRedirect(reverse("default"))        else:            state = "login_error"
context = { "active_menu": 'default', "user": None, "state": state } return render(request, "menuapp/login.html", context)
复制代码


修改完毕之后,运行网站,结果出现如下错误,反复查询之后,在 urls.py 文件中,一个路由的名字写错了,修改如下:


from django.urls import pathfrom . import views
urlpatterns = [ path("", views.index, name="default"), path("register", views.register, name="register"), path("login", views.login, name="login")]
复制代码


上述代码成功解决下述问题。



以上代码正常运行的结果是,当用户正常登录之后,会跳转到首页,重新去访问登录页面,也会跳转到首页,简单理解就是你的登录页面进不去了,除非手动删除本地 cookie。

9.3 用户注销

注销不需要有页面,但是需要完成 views.py 中的 logout 函数。


def logout(request):    # 注销登录    auth.logout(request)    return HttpResponseRedirect(reverse("default"))
复制代码


修改完毕 views.py 代码之后,还要在 urls.py 中新增注销用户的路由。


urlpatterns = [    path("", views.index, name="default"),    path("register", views.register, name="register"),    path("login", views.login, name="login"),    path("logout", views.logout, name="logout")]
复制代码


访问 http://127.0.0.1:8000/logout 实现注销,同时 http://127.0.0.1:8000/login 可以再次访问。

9.4 本篇博客小节

本篇博客对菜谱系统的登录与注册页面逻辑进行了补充,实现了基于内置 User 模型的增加操作。文章难度虽然不大,但是核心知识点比较多,并且有许多位置的技术知识点被后置了,这些内容在后续都将为你展开,一起坚持学习吧。


发布于: 2021 年 08 月 18 日阅读数: 4
用户头像

爬虫 100 例作者,蓝桥签约作者,博客专家 2021.02.06 加入

6 年产品经理+教学经验,3 年互联网项目管理经验; 互联网资深爱好者; 沉迷各种技术无法自拔,导致年龄被困在 25 岁; CSDN 爬虫 100 例作者。 个人公众号“梦想橡皮擦”。

评论

发布
暂无评论
Python Web 菜谱项目再次前进一步,从应用层了解内置用户认证系统