侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Django 用户认证组件使用详解

框架(架构)  /  管理员 发布于 7年前   196

一、auth模块

# 创建超级用户python manage.py createsuperuserfrom django.contrib import auth

django.contrib.auth中提供了许多方法:

authenticate()

提供了用户认证功能,即验证用户名以及密码是否正确,一般需要username 、password两个关键字参数。

如果认证成功(用户名和密码正确有效),便会返回一个 User 对象。

authenticate()会在该 User 对象上设置一个属性来标识后端已经认证了该用户,且该信息在后续的登录过程中是需要的。

from django.contrib.auth import authenticateuser = authenticate(username="user",password="pwd")

login(HttpRequest, user)

该函数接受一个HttpRequest对象,以及一个认证了的User对象;该函数实现一个用户登录的功能。它本质上会在后端为该用户生成相关session数据。

from django.contrib.auth import authenticate, logindef log_in(request): if request.method == "POST":  user = request.POST.get("username")  pwd = request.POST.get("password")  user = authenticate(username=user, password=pwd)  if user is not None:   login(request, user)   # Redirect to a success page   ...  else:   # Return an "invalid login" error message.   ... return render(request, "login.html")

logout(request)注销用户

该函数接受一个HttpRequest对象,无返回值。当调用该函数时,当前请求的session信息会全部清除。该用户即使没有登录,使用该函数也不会报错。

from django.contrib.auth import logoutdef log_out(request): logout(request) # Redirect to a success page.

二、User对象

User 对象属性:username,password(必填项);password用哈希算法保存到数据库

is_staff:用户是否拥有网站的管理权限

is_active:是否允许用户登录。设置为"False",可以不用删除用户来禁止用户登录

is_authenticated()

如果是真正的 User 对象,返回值恒为 True;用于检查用户是否已经通过了认证。

通过认证并不意味着用户拥有任何权限,甚至也不检查该用户是否处于激活状态,这只是表明用户成功的通过了认证。 这个方法很重要,在后台用request.user.is_authenticated()判断用户是否已经登录,如果为 true 则可以向前台展示 request.user.name。

要求:

  • 用户登陆后才能访问某些页面
  • 如果用户没有登录就访问该页面的话直接跳到登录页面
  • 用户在跳转的登陆界面中完成登陆后,自动访问跳转到之前访问的地址

方法1:

def my_view(request): if not request.user.is_authenticated():  return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))

方法2:

django已经为我们设计好了一个用于此种情况的装饰器:login_requierd()

from django.contrib.auth.decorators import login_required@login_requireddef my_view(request): ...

使用login_requierd()注意:

若用户没有登录,则会跳转到django默认的登录URL '/accounts/login/ ';并传递当前访问url的绝对路径 (登陆成功后,会重定向到该路径)。

如果需要自定义登录的URL,则需要在settings.py文件中通过LOGIN_URL进行修改。

LOGIN_URL = "/login/" # 这里配置成项目登录页面的路由

create_user()创建用户

from django.contrib.auth.models import Useruser = User.objects.create_user(username="", password="", email="", ...)

create_superuser()创建超级用户

from django.contrib.auth.models import Useruser = User.objects.create_superuser(username="", password="", email="", ...)

check_password(password)

检查密码是否正确的方法;密码正确返回True,否则返回False。

ret = user.check_password("密码")

set_password(password)

一个修改密码的方法,接收要设置的新密码作为参数。

注意:设置完一定要调用User对象的save方法!!!

user.set_password(password="")user.save()

修改密码示例:

@login_requireddef alter_password(request): user = request.user err_msg = "" if request.method == 'POST':  old_password = request.POST.get("old_password", "")  new_password = request.POST.get("new_password", "")  repeat_password = request.POST.get("repeat_password", "")  if user.check_password(old_password):   if not new_password:    err_msg = "新密码不能为空"   elif new_password != repeat_password:    err_msg = "两次密码不一致"   else:    user.set_password(new_password)    user.save()    return redirect("/log_in/")  else:   err_msg = "原密码输入错误" content = {  "err_msg": err_msg, } return render(request, "alter_password.html", content)

三、扩展默认的auth_user表

通过继承内置的 AbstractUser 类,来定义一个自己的Model类。这样既能根据项目需求灵活的设计用户表,又能使用Django强大的认证系统了。

# models.pyfrom django.db import modelsfrom django.contrib.auth.models import AbstractUserclass UserInfo(AbstractUser): age = models.IntegerField(default=18) phone = models.CharField(max_length=11, null=True, unique=True) def __str__(self):  return self.username

注意:

按上面的方式扩展了内置的auth_user表之后,一定要在settings.py中告诉Django,我现在使用我新定义的UserInfo表来做用户认证:

# 引用Django自带的User表,继承使用时需要设置AUTH_USER_MODEL = "app名.UserInfo"

一旦我们指定了新的认证系统所使用的表,我们就需要重新在数据库中创建该表,而不能继续使用原来默认的auth_user表了。

四、示例

views.py

from django.shortcuts import render, redirectfrom django.contrib.auth import authenticate, login, logoutfrom django.contrib.auth.decorators import login_required# from django.contrib.auth.models import Userfrom appxx import modelsdef sign_up(request):  error_msg = ""  if request.method == "POST":    user = request.POST.get("username")    pwd = request.POST.get("password")    if models.UserInfo.objects.filter(username=user):      error_msg = "用户已存在"    else:      new_user = models.UserInfo.objects.create_user(username=user, password=pwd)      new_user.save()      return redirect("/login/")  content = {    "error_msg": error_msg  }  return render(request, "register.html", content)def log_in(request):  if request.method == "POST":    user = request.POST.get("username")    pwd = request.POST.get("password")    user = authenticate(username=user, password=pwd)    if user is not None:      login(request, user)      return redirect("/index/")  return render(request, "login.html")@login_requireddef index(request):  return render(request, "index.html")def log_out(request):  logout(request)  return redirect("/login/")

sign_up 函数部分原本使用 User.objects,但因为使用了 UserInfo 表代替了 django 内置的 auth_user 表,所以需要改为 models.UserInfo.objects

login.html

<!DOCTYPE html><html lang="zh-cn"><head>  <meta charset="UTF-8">  <title>登录</title></head><body><h1>登录页面</h1><form action="/login/" method="post">  {% csrf_token %}  <p>    <label for="username">账号:</label>    <input type="text" id="username" name="username">  </p>  <p>    <label for="password">密码:</label>    <input type="password" id="password" name="password">  </p>  <p>    <label for="submit"></label>    <input type="submit" value="登录">  </p></form></body></html>

register.html

<!DOCTYPE html><html lang="zh-cn"><head>  <meta charset="UTF-8">  <title>注册</title></head><body><h1>注册页面</h1><form action="/register/" method="post">  {{ error_msg }}  {% csrf_token %}  <p>    <label for="username">账号:</label>    <input type="text" id="username" name="username">  </p>  <p>    <label for="password">密码:</label>    <input type="password" id="password" name="password">  </p>  <p>    <label for="submit"></label>    <input type="submit" value="注册">  </p></form></body></html>

index.html

<!DOCTYPE html><html lang="zh-cn"><head>  <meta charset="UTF-8">  <title>index</title></head><body><h1>index页面</h1><p>欢迎:{{ request.user.username }}</p><a href="https:logout/">注销登录</a></body></html>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


  • 上一条:
    Django 静态文件配置过程详解
    下一条:
    Django 开发调试工具 Django-debug-toolbar使用详解
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Filament v3.1版本发布(0个评论)
    • docker + gitea搭建一个git服务器流程步骤(0个评论)
    • websocket的三种架构方式使用优缺点浅析(0个评论)
    • ubuntu20.4系统中宿主机安装nginx服务,docker容器中安装php8.2实现运行laravel10框架网站(0个评论)
    • phpstudy_pro(小皮面板)中安装最新php8.2.9版本流程步骤(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2018-05
    • 2020-02
    • 2020-03
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-11
    • 2021-03
    • 2021-09
    • 2021-10
    • 2021-11
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-08
    • 2023-08
    • 2023-10
    • 2023-12
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客