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写的贪吃蛇游戏例子
Jun 16 Python
python创建进程fork用法
Jun 04 Python
深入解析Python中的urllib2模块
Nov 13 Python
详解Python列表赋值复制深拷贝及5种浅拷贝
May 15 Python
python threading和multiprocessing模块基本用法实例分析
Jul 25 Python
Python使用百度api做人脸对比的方法
Aug 28 Python
简单了解python协程的相关知识
Aug 31 Python
Python实现非正太分布的异常值检测方式
Dec 09 Python
Python使用pdb调试代码的技巧
May 03 Python
python ETL工具 pyetl
Jun 07 Python
详解Selenium-webdriver绕开反爬虫机制的4种方法
Oct 28 Python
Python3压缩和解压缩实现代码
Mar 01 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
漫威DC御用漫画家去世 他的表情包曾走红网络
2020/04/09 欧美动漫
用PHP读取RSS feed的代码
2008/08/01 PHP
php excel reader读取excel内容存入数据库实现代码
2012/12/06 PHP
如何使用php绘制在图片上的正余弦曲线
2013/06/08 PHP
php获取URL中带#号等特殊符号参数的解决方法
2014/09/02 PHP
php实现图片按比例截取的方法
2017/02/06 PHP
php array_chunk()函数用法与注意事项
2019/07/12 PHP
探讨JavaScript中声明全局变量三种方式的异同
2013/12/03 Javascript
JavaScript作用域链示例分享
2014/05/27 Javascript
初始Nodejs
2014/11/08 NodeJs
Node.js 去掉种子(torrent)文件里的邪恶信息
2015/03/27 Javascript
readonly和disabled属性的区别
2015/07/26 Javascript
详解vue过滤器在v2.0版本用法
2017/06/01 Javascript
JavaScript30 一个月纯 JS 挑战中文指南(英文全集)
2017/07/23 Javascript
使用flow来规范javascript的变量类型
2019/09/12 Javascript
JavaScript动态生成表格的示例
2020/11/02 Javascript
Python计算三角函数之asin()方法的使用
2015/05/15 Python
python实现手机通讯录搜索功能
2018/02/22 Python
使用Python自动生成HTML的方法示例
2019/08/06 Python
基于Python获取照片的GPS位置信息
2020/01/20 Python
Windows系统下pycharm中的pip换源
2020/02/23 Python
使用python+poco+夜神模拟器进行自动化测试实例
2020/04/23 Python
python如何导出微信公众号文章方法详解
2020/08/31 Python
CSS3中利用animation属性创建雪花飘落特效
2014/05/14 HTML / CSS
联想新加坡官方网站:Lenovo Singapore
2017/10/24 全球购物
Sephora丝芙兰马来西亚官方网站:国际化妆品购物
2018/03/15 全球购物
标记环网Toke Ring IEEE802.5
2014/05/26 面试题
给水排水工程专业毕业生推荐信
2013/10/28 职场文书
求职信的七个关键技巧
2014/02/05 职场文书
法学院毕业生求职信
2014/06/25 职场文书
法制教育演讲稿
2014/09/10 职场文书
四风问题个人对照检查材料
2014/09/26 职场文书
党支部四风整改方案
2014/10/25 职场文书
入股协议书范本
2014/11/01 职场文书
2016猴年春节问候语
2015/11/11 职场文书
2016年社区中秋节活动总结
2016/04/05 职场文书