详解Django之auth模块(用户认证)


Posted in Python onApril 17, 2018

auth模块简介

auth模块是对登录认证方法的一种封装,之前我们获取用户输入的用户名及密码后需要自己从user表里查询有没有用户名和密码符合的对象,

而有了auth模块之后就可以很轻松的去验证用户的登录信息是否存在于数据库中。

除此之外,auth还对session做了一些封装,方便我们校验用户是否已登录

auth里的方法

如果想使用auth模块的方法,必须要先导入auth模块

from django.contrib import auth

django.contrib.auth中提供了许多方法,这里主要介绍其中的四个:

1 、authenticate()  

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

如果认证信息有效,会返回一个  User  对象。authenticate()会在User 对象上设置一个属性标识那种认证后端认证了该用户,且该信息在后面的登录过程中是需要的。当我们试图登陆一个从数据库中直接取出来不经过authenticate()的User对象会报错的!!

user = authenticate(username='someone',password='somepassword')

2 、login(HttpRequest, user)

该函数接受一个HttpRequest对象,以及一个认证了的User对象

此函数使用django的session框架给某个已认证的用户附加上session id等信息。

from django.contrib.auth import authenticate, login
  
def my_view(request):
  username = request.POST['username']
  password = request.POST['password']
  user = authenticate(username=username, password=password)
  if user is not None:
    login(request, user)
    # Redirect to a success page.
    ...
  else:
    # Return an 'invalid login' error message.
    ...

3 、logout(request) 注销用户

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

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

4 、user对象的 is_authenticated()

要求:

1  用户登陆后才能访问某些页面,

2  如果用户没有登录就访问该页面的话直接跳到登录页面

3  用户在跳转的登陆界面中完成登陆后,自动访问跳转到之前访问的地址

方法1:

直接用auth的is_authenticated()方法验证

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

方法2:

根据request.user.username来验证,如果为空,则说明没有登录

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

方法3:

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

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

若用户没有登录,则会跳转到django默认的 登录URL '/accounts/login/ ' (这个值可以在settings文件中通过LOGIN_URL进行修改)。并传递  当前访问url的绝对路径 ( 登陆成功后,会重定向到该路径 )。

user对象

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

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

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

2.1 、is_authenticated()

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

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

2.2 、创建用户

使用 create_user 辅助函数创建用户:

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

2.3 、check_password(passwd)

user = User.objects.get(username=' ')
if user.check_password(passwd):
  ......

用户需要修改密码的时候 首先要让他输入原来的密码 ,如果给定的字符串通过了密码检查,返回  True

使用 set_password() 来修改密码

user = User.objects.get(username='')
user.set_password(password='')
user.save 

2.5 、简单示例

注册:

def sign_up(request):
 
  state = None
  if request.method == 'POST':
 
    password = request.POST.get('password', '')
    repeat_password = request.POST.get('repeat_password', '')
    email=request.POST.get('email', '')
    username = request.POST.get('username', '')
    if User.objects.filter(username=username):
        state = 'user_exist'
    else:
        new_user = User.objects.create_user(username=username, password=password,email=email)
        new_user.save()
 
        return redirect('/book/')
  content = {
    'state': state,
    'user': None,
  }
  return render(request, 'sign_up.html', content)

修改密码:

@login_required
def set_password(request):
  user = request.user
  state = None
  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:
        state = 'empty'
      elif new_password != repeat_password:
        state = 'repeat_error'
      else:
        user.set_password(new_password)
        user.save()
        return redirect("/log_in/")
    else:
      state = 'password_error'
  content = {
    'user': user,
    'state': state,
  }
  return render(request, 'set_password.html', content)

自己创建User表

需要注意的是,以上的所有操作,都是针对django自动创建的auth_user表的,我们可以看一下这张表的结构

详解Django之auth模块(用户认证)

这是django给我们自动创建的一张user表,而如果要用auth模块,就必须要使用(或继承)这张表。

继承表的好处是我们可以增加一些自己需要的字段,并且同时可以使用auth模块提供的接口、方法

下面就讲一下继承auth的方法:

1、导入AbstractUser类,并且写一个自定义的类,继承AbstractUser类,如下:

from django.contrib.auth.models import AbstractUser

class UserInfo(AbstractUser):
  """
  用户信息
  """
  nid = models.AutoField(primary_key=True)
  telephone = models.CharField(max_length=11, null=True, unique=True)
  ......

需要注意的是,UserInfo表里就不需要有auth_user里重复的字段了,比如说username以及password等,但是还是可以直接使用这些字段的,并且django会自动将password进行加密

2、这样写完之后,还需要在setting.py文件里配置:

AUTH_USER_MODEL = 'blog.UserInfo'

这样,django就知道从blog项目下的models去查找UserInfo这张表了

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

Python 相关文章推荐
初学Python实用技巧两则
Aug 29 Python
wxPython窗口的继承机制实例分析
Sep 28 Python
python+requests+unittest API接口测试实例(详解)
Jun 10 Python
基于Python代码编辑器的选用(详解)
Sep 13 Python
Python数据结构之哈夫曼树定义与使用方法示例
Apr 22 Python
Python实现的根据IP地址计算子网掩码位数功能示例
May 23 Python
Flask框架中request、请求钩子、上下文用法分析
Jul 23 Python
计算Python Numpy向量之间的欧氏距离实例
May 22 Python
Java ExcutorService优雅关闭方式解析
May 30 Python
keras的load_model实现加载含有参数的自定义模型
Jun 22 Python
python3.x中安装web.py步骤方法
Jun 23 Python
浅析关于Keras的安装(pycharm)和初步理解
Oct 23 Python
numpy中实现ndarray数组返回符合特定条件的索引方法
Apr 17 #Python
python中找出numpy array数组的最值及其索引方法
Apr 17 #Python
详谈Numpy中数组重塑、合并与拆分方法
Apr 17 #Python
基于numpy.random.randn()与rand()的区别详解
Apr 17 #Python
Python实现求解括号匹配问题的方法
Apr 17 #Python
django 通过ajax完成邮箱用户注册、激活账号的方法
Apr 17 #Python
对numpy中array和asarray的区别详解
Apr 17 #Python
You might like
WINDOWS服务器安装多套PHP的另类解决方案
2006/10/09 PHP
PHP的中问验证码
2006/11/25 PHP
php win下Socket方式发邮件类
2009/08/21 PHP
Yii2-GridView 中让关联字段带搜索和排序功能示例
2017/01/21 PHP
PHP使用PDO、mysqli扩展实现与数据库交互操作详解
2019/07/20 PHP
JS IE和FF兼容性问题汇总
2009/02/09 Javascript
JavaScript 拾漏补遗
2009/12/27 Javascript
原始的js代码和jquery对比体会
2013/09/10 Javascript
Jquery Uploadify上传带进度条的简单实例
2014/02/12 Javascript
PHP PDO操作总结
2014/11/17 Javascript
使表格的标题列可左右拉伸jquery插件封装
2014/11/24 Javascript
jquery实现鼠标滑过小图时显示大图的方法
2015/01/14 Javascript
通过JS判断联网类型和连接状态的实现代码
2015/04/01 Javascript
JavaScript中的数组遍历forEach()与map()方法以及兼容写法介绍
2016/05/19 Javascript
原生js仿jquery一些常用方法(必看篇)
2016/09/20 Javascript
最实用的jQuery分页插件
2016/10/09 Javascript
值得分享和收藏的xmlplus组件学习教程
2017/05/05 Javascript
浅谈Vue render函数在ElementUi中的应用
2018/09/06 Javascript
浅谈vue限制文本框输入数字的正确姿势
2019/09/02 Javascript
解决vue自定义全局消息框组件问题
2019/11/22 Javascript
[01:11]辉夜杯战队访谈宣传片—CDEC.Y
2015/12/26 DOTA
Python基础教程之浅拷贝和深拷贝实例详解
2017/07/15 Python
Python 模拟登陆的两种实现方法
2017/08/10 Python
python ftp 按目录结构上传下载的实现代码
2018/09/12 Python
用Python实现最速下降法求极值的方法
2019/07/10 Python
sublime3之内网安装python插件Anaconda的流程
2020/11/10 Python
英国床和浴室商场:Bed & Bath Emporium
2018/05/20 全球购物
介绍一下grep命令的使用
2015/06/12 面试题
毕业生怎样写好自荐信
2013/11/11 职场文书
成考报名单位证明范本
2014/01/16 职场文书
社会体育专业大学生职业生涯规划书
2014/09/17 职场文书
政风行风评议工作总结
2014/10/21 职场文书
2015年员工工作总结范文
2015/04/08 职场文书
单位更名证明
2015/06/18 职场文书
一百条裙子读书笔记
2015/07/01 职场文书
vue生命周期钩子函数以及触发时机
2022/04/26 Vue.js