Django 用户认证组件使用详解
Django 用户认证组件使用详解
一、auth模块
1
2
3
|
# 创建超级用户 python manage.py createsuperuser from django.contrib import auth |
django.contrib.auth中提供了许多方法:
authenticate()
提供了用户认证功能,即验证用户名以及密码是否正确,一般需要username 、password两个关键字参数。
如果认证成功(用户名和密码正确有效),便会返回一个 User 对象。
authenticate()会在该 User 对象上设置一个属性来标识后端已经认证了该用户,且该信息在后续的登录过程中是需要的。
1
2
3
|
from django.contrib.auth import authenticate user = authenticate(username= "user" ,password= "pwd" ) |
login(HttpRequest, user)
该函数接受一个HttpRequest对象,以及一个认证了的User对象;该函数实现一个用户登录的功能。它本质上会在后端为该用户生成相关session数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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信息会全部清除。该用户即使没有登录,使用该函数也不会报错。
1
2
3
4
5
|
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:
1
2
3
|
def my_view(request): if not request.user.is_authenticated(): return redirect( '%s?next=%s' % (settings.LOGIN_URL, request.path)) |
方法2:
django已经为我们设计好了一个用于此种情况的装饰器:login_requierd()
1
2
3
4
5
|
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进行修改。
1
|
LOGIN_URL = "/login/" # 这里配置成项目登录页面的路由 |
create_user()创建用户
1
2
3
|
from django.contrib.auth.models import User user = User.objects.create_user(username = " ", password=" ", email=" ", ...) |
create_superuser()创建超级用户
1
2
3
|
from django.contrib.auth.models import User user = User.objects.create_superuser(username = " ", password=" ", email=" ", ...) |
check_password(password)
检查密码是否正确的方法;密码正确返回True,否则返回False。
1
|
ret = user.check_password( "密码" ) |
set_password(password)
一个修改密码的方法,接收要设置的新密码作为参数。
注意:设置完一定要调用User对象的save方法!!!
1
2
|
user.set_password(password = "") user.save() |
修改密码示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
@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强大的认证系统了。
1
2
3
4
5
6
7
8
9
10
11
12
|
# 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表来做用户认证:
1
2
|
# 引用Django自带的User表,继承使用时需要设置 AUTH_USER_MODEL = "app名.UserInfo" |
一旦我们指定了新的认证系统所使用的表,我们就需要重新在数据库中创建该表,而不能继续使用原来默认的auth_user表了。
四、示例
views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<!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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<!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
1
2
3
4
5
6
7
8
9
10
11
12
|
<!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 > |
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。