经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Django » 查看文章
Django 用户认证组件使用详解
来源:jb51  时间:2019/7/23 13:14:27  对本文有异议

一、auth模块

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

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

authenticate()

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

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

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

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

login(HttpRequest, user)

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

  1. from django.contrib.auth import authenticate, login
  2.  
  3. def log_in(request):
  4. if request.method == "POST":
  5. user = request.POST.get("username")
  6. pwd = request.POST.get("password")
  7. user = authenticate(username=user, password=pwd)
  8. if user is not None:
  9. login(request, user)
  10. # Redirect to a success page
  11. ...
  12. else:
  13. # Return an "invalid login" error message.
  14. ...
  15. return render(request, "login.html")

logout(request)注销用户

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

  1. from django.contrib.auth import logout
  2.  
  3. def log_out(request):
  4. logout(request)
  5. # 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:

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

方法2:

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

  1. from django.contrib.auth.decorators import login_required
  2.  
  3. @login_required
  4. def my_view(request):
  5. ...

使用login_requierd()注意:

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

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

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

create_user()创建用户

  1. from django.contrib.auth.models import User
  2.  
  3. user = User.objects.create_userusername="", password="", email="", ...)

create_superuser()创建超级用户

  1. from django.contrib.auth.models import User
  2.  
  3. user = User.objects.create_superuserusername="", password="", email="", ...)

check_password(password)

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

  1. ret = user.check_password("密码")

set_password(password)

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

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

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

修改密码示例:

  1. @login_required
  2. def alter_password(request):
  3. user = request.user
  4. err_msg = ""
  5. if request.method == 'POST':
  6. old_password = request.POST.get("old_password", "")
  7. new_password = request.POST.get("new_password", "")
  8. repeat_password = request.POST.get("repeat_password", "")
  9. if user.check_password(old_password):
  10. if not new_password:
  11. err_msg = "新密码不能为空"
  12. elif new_password != repeat_password:
  13. err_msg = "两次密码不一致"
  14. else:
  15. user.set_password(new_password)
  16. user.save()
  17. return redirect("/log_in/")
  18. else:
  19. err_msg = "原密码输入错误"
  20. content = {
  21. "err_msg": err_msg,
  22. }
  23. return render(request, "alter_password.html", content)

三、扩展默认的auth_user表

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

  1. # models.py
  2.  
  3. from django.db import models
  4. from django.contrib.auth.models import AbstractUser
  5.  
  6.  
  7. class UserInfo(AbstractUser):
  8. age = models.IntegerField(default=18)
  9. phone = models.CharField(max_length=11, null=True, unique=True)
  10.  
  11. def __str__(self):
  12. return self.username

注意:

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

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

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

四、示例

views.py

  1. from django.shortcuts import render, redirect
  2. from django.contrib.auth import authenticate, login, logout
  3. from django.contrib.auth.decorators import login_required
  4. # from django.contrib.auth.models import User
  5. from appxx import models
  6.  
  7.  
  8. def sign_up(request):
  9. error_msg = ""
  10. if request.method == "POST":
  11. user = request.POST.get("username")
  12. pwd = request.POST.get("password")
  13. if models.UserInfo.objects.filter(username=user):
  14. error_msg = "用户已存在"
  15. else:
  16. new_user = models.UserInfo.objects.create_user(username=user, password=pwd)
  17. new_user.save()
  18. return redirect("/login/")
  19. content = {
  20. "error_msg": error_msg
  21. }
  22. return render(request, "register.html", content)
  23.  
  24.  
  25. def log_in(request):
  26. if request.method == "POST":
  27. user = request.POST.get("username")
  28. pwd = request.POST.get("password")
  29. user = authenticate(username=user, password=pwd)
  30. if user is not None:
  31. login(request, user)
  32. return redirect("/index/")
  33. return render(request, "login.html")
  34.  
  35.  
  36. @login_required
  37. def index(request):
  38. return render(request, "index.html")
  39.  
  40.  
  41. def log_out(request):
  42. logout(request)
  43. return redirect("/login/")

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

login.html

  1. <!DOCTYPE html>
  2. <html lang="zh-cn">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>登录</title>
  6. </head>
  7. <body>
  8. <h1>登录页面</h1>
  9. <form action="/login/" method="post">
  10. {% csrf_token %}
  11. <p>
  12. <label for="username">账号:</label>
  13. <input type="text" id="username" name="username">
  14. </p>
  15. <p>
  16. <label for="password">密码:</label>
  17. <input type="password" id="password" name="password">
  18. </p>
  19. <p>
  20. <label for="submit"></label>
  21. <input type="submit" value="登录">
  22. </p>
  23. </form>
  24. </body>
  25. </html>

register.html

  1. <!DOCTYPE html>
  2. <html lang="zh-cn">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>注册</title>
  6. </head>
  7. <body>
  8. <h1>注册页面</h1>
  9. <form action="/register/" method="post">
  10. {{ error_msg }}
  11. {% csrf_token %}
  12. <p>
  13. <label for="username">账号:</label>
  14. <input type="text" id="username" name="username">
  15. </p>
  16. <p>
  17. <label for="password">密码:</label>
  18. <input type="password" id="password" name="password">
  19. </p>
  20. <p>
  21. <label for="submit"></label>
  22. <input type="submit" value="注册">
  23. </p>
  24. </form>
  25. </body>
  26. </html>

index.html

  1. <!DOCTYPE html>
  2. <html lang="zh-cn">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>index</title>
  6. </head>
  7. <body>
  8. <h1>index页面</h1>
  9. <p>欢迎:{{ request.user.username }}</p>
  10. <a href="/logout/">注销登录</a>
  11. </body>
  12. </html>

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

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号