Django 用户认证组件使用详解


Posted in Python onJuly 23, 2019

一、auth模块

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

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

authenticate()

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

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

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

from django.contrib.auth import authenticate

user = authenticate(username="user",password="pwd")

login(HttpRequest, user)

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

from django.contrib.auth import authenticate, login

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)
   # 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 logout

def 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_required
def 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 User

user = User.objects.create_user(username="", password="", email="", ...)

create_superuser()创建超级用户

from django.contrib.auth.models import User

user = 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_required
def 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.py

from django.db import models
from django.contrib.auth.models import AbstractUser


class 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, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
# from django.contrib.auth.models import User
from appxx import models


def 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_required
def 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="/logout/">注销登录</a>
</body>
</html>

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

Python 相关文章推荐
python正则表达式re模块详细介绍
May 29 Python
详解Python3中yield生成器的用法
Aug 20 Python
解决pycharm运行出错,代码正确结果不显示的问题
Nov 30 Python
详解10个可以快速用Python进行数据分析的小技巧
Jun 24 Python
对Python获取屏幕截图的4种方法详解
Aug 27 Python
python高阶函数map()和reduce()实例解析
Mar 16 Python
python如何调用java类
Jul 05 Python
Python 如何测试文件是否存在
Jul 31 Python
Appium+Python实现简单的自动化登录测试的实现
Jan 26 Python
Python实现疫情地图可视化
Feb 05 Python
Python selenium模拟网页点击爬虫交管12123违章数据
May 26 Python
Python机器学习之基于Pytorch实现猫狗分类
Jun 08 Python
pandas DataFrame 警告(SettingWithCopyWarning)的解决
Jul 23 #Python
利用Python库Scapy解析pcap文件的方法
Jul 23 #Python
python3.x提取中文的正则表达式示例代码
Jul 23 #Python
Python Pandas 箱线图的实现
Jul 23 #Python
Django 开发调试工具 Django-debug-toolbar使用详解
Jul 23 #Python
Pandas分组与排序的实现
Jul 23 #Python
Python项目 基于Scapy实现SYN泛洪攻击的方法
Jul 23 #Python
You might like
PHP编程网上资源导航
2006/10/09 PHP
PHP STRING 陷阱原理说明
2010/07/24 PHP
php下利用curl判断远程文件是否存在的实现代码
2011/10/08 PHP
PHP 杂谈《重构-改善既有代码的设计》之三 重新组织数据
2012/04/09 PHP
php实现数组筛选奇数和偶数示例
2014/04/11 PHP
php实现获取文件mime类型的方法
2015/02/11 PHP
jquery validate.js表单验证的基本用法入门
2010/05/13 Javascript
jquery下checked取值问题的解决方法
2012/08/09 Javascript
基于JQuery 滑动与动画的说明介绍
2013/04/18 Javascript
js opener的使用详解
2014/01/11 Javascript
jquery.Ajax()方法调用Asp.Net后台的方法解析
2014/02/13 Javascript
javascript面向对象之共享成员属性与方法及prototype关键字用法
2015/01/13 Javascript
AngularJS实现全选反选功能
2015/12/08 Javascript
JS控制静态页面传递参数并获取参数应用
2016/08/10 Javascript
Vue2.0 slot分发内容与props验证的方法
2017/12/12 Javascript
监控微信小程序中的慢HTTP请求过程详解
2019/07/05 Javascript
详解简单易懂的 ES6 Iterators 指南和示例
2019/09/24 Javascript
[01:13]DOTA2群星解读国服召集令 一起说出回归的理由
2013/07/17 DOTA
详解Python中的文件操作
2016/08/28 Python
对PyQt5基本窗口控件 QMainWindow的使用详解
2019/06/19 Python
python将字符串转换成json的方法小结
2019/07/09 Python
python 随机森林算法及其优化详解
2019/07/11 Python
python使用ctypes调用扩展模块的实例方法
2020/01/28 Python
在python中修改.properties文件的操作
2020/04/08 Python
记一次Django响应超慢的解决过程
2020/09/17 Python
Reebonz中国官网:新加坡奢侈品购物网站
2017/03/17 全球购物
AP澳洲中文网:澳洲正品直邮,包税收件无忧
2019/07/12 全球购物
德国婴儿服装和婴儿用品购买网站:Baby Sweets
2019/12/08 全球购物
小加工厂管理制度
2014/01/21 职场文书
企业车辆管理制度
2014/01/24 职场文书
大课间体育活动方案
2014/03/12 职场文书
《大海那边》教学反思
2014/04/09 职场文书
网球场地租赁协议范本
2014/10/07 职场文书
颐和园英文导游词
2015/01/30 职场文书
郭明义电影观后感
2015/06/08 职场文书
幼儿体育课教学反思
2016/02/16 职场文书