Django内置的认证系统

选择使用django默认使用的db.sqlite

1.下载驱动  

2.点击files选框的...按钮那里,选择对应项目根目录下的db.sqlite

3.Python3 manage.py migrate

4.Python3 manage.py createsuperuser,就可以在命令行创建一个超级用户的账户

导入auth模块

from django.contrib import auth

方法(部分)

authenticate()  

这是用于验证用户名以及密码是否正确,一般需要username  password两个关键字参数

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

用法:user = authenticate(username='user',password='password')

当我们试图登陆一个从数据库中直接取出来不经过authenticate()的User对象时会报错!!!

login(request, user)  

该函数接受一个HttpRequest对象,以及一个认证了的User对象.此函数使用django的session框架给某个已认证的用户附加上session id等信息。

 1 from django.contrib.auth import authenticate, login
 2 
 3   
 4 def my_view(request):
 5 
 6   username = request.POST['username']
 7 
 8   password = request.POST['password']
 9 
10   user = authenticate(username=username, password=password)
11 
12   if user is not None:
13 
14     login(request, user)
15 
16     # Redirect to a success page.
17 
18     ...
19 
20   else:
21 
22     # Return an 'invalid login' error message.
23 
24     ...
View Code

logout(request) 注销用户 

from django.contrib.auth import logout

def logout(request):
    auth.logout(request)
    return redirect("/login/")

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

is_authenticated()

用于判断当前请求是否通过了认证

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

login_requierd()

用于快捷地给某个视图添加登录校验

from django.contrib.auth.decorators import login_required

@login_required
def my_view(request):
  ...

若用户没有登录,则会跳转到django默认的 登录URL '/accounts/login/ ' (这个值可以在settings.py文件中通过LOGIN_URL进行修改)。

# 设置这个网站默认登录的页面

LOGIN_URL = "/login/"

并传递当前访问url的绝对路径 (登陆成功后,会重定向到该路径)。

User对象

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

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

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

is_authenticated()如果是真正的 User 对象,返回值恒为 True 。 用于检查用户是否已经通过了认证。通过认证并不意味着用户拥有任何权限,这个方法甚至也不检查该用户是否处于激活状态,只是表明用户成功的通过了认证。

创建用户

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

from django.contrib.auth.models import User

user = User.objects.create_user(username='用户名',password='密码',email='邮件地址'

check_password(passwd)

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

ok = user.check_password('密码')

set_password()

用于修改密码

user = User.objects.get(username='用户名')

user.set_password(password='设置的密码')

user.save()

设置完密码后,一定要调用用户对象的save方法保存修改后的

 1 @login_required
 2 def set_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         # 检查旧密码是否正确
10         if user.check_password(old_password):
11             if not new_password:
12                 err_msg = '新密码不能为空'
13             elif new_password != repeat_password:
14                 err_msg = '两次密码不一致'
15             else:
16                 user.set_password(new_password)
17                 user.save()
18                 return redirect("/login/")
19         else:
20             err_msg = '原密码输入错误'
21     content = {
22         'err_msg': err_msg,
23     }
24     return render(request, 'set_password.html', content)
25 
26  
举个栗子

扩展auth_user表

继承内置的auth_user表的对应的类,来定义一个自己的ORM类。

from django.contrib.auth.models import AbstractUser

class UserInfo(AbstractUser):
    """
    用户信息表
    """
    nid = models.AutoField(primary_key=True)
    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"

将Django的form组件和认证放在一起的小栗子:

 1 from django.shortcuts import render, redirect, HttpResponse
 2 from django.contrib import auth
 3 from django.contrib.auth.models import User
 4 from django.contrib.auth.decorators import login_required
 5 from about_auth import froms
 6 
 7 
 8 # Create your views here.
 9 def login(request):
10     if request.method == 'POST':
11         form_obj = froms.LoginForm(request.POST)
12         if form_obj.is_valid():
13             dic = form_obj.cleaned_data
14             # 验证用户名和密码是否正确
15             user = auth.authenticate(username=dic["username"], password=dic["password"])
16             if user:
17                 # 调用内置的login方法
18                 # 1.生成session数据,把session写入cookie
19                 # 后来每次进来的时候,request.user拿到当前值
20                 auth.login(request, user)
21                 return redirect('/home/')
22         else:
23             print(form_obj)
24             return render(request,'login.html',{'form_obj':form_obj, })
25     form_obj = froms.LoginForm()
26     return render(request, 'login.html', {'form_obj': form_obj})
27 
28 
29 def register(request):
30     if request.method == 'POST':
31         form_obj = froms.RegForm(request.POST)
32         if form_obj.is_valid():
33             # 创建普通用户的专用方法
34             User.objects.create_user(username=form_obj.cleaned_data["username"],
35                                      password=form_obj.cleaned_data["password"])
36             return redirect("/login/")
37         else:
38             return render(request, 'register.html', {'form_obj': form_obj})
39     form_obj = froms.RegForm()
40     return render(request, 'register.html', {'form_obj': form_obj})
41 
42 
43 @login_required
44 def home(request):
45     return render(request, 'home.html')
46 
47 
48 @login_required
49 def set_pwd(request):
50     if request.method == 'POST':
51         form_obj = froms.SetPwdForm(request.POST)
52         if form_obj.is_valid():
53             dic = form_obj.cleaned_data
54             # 先校验原密码对不对
55             user_obj = request.user
56             if user_obj.check_password(dic["old_pwd"]):
57                 if dic["new_pwd"] == dic["con_pwd"]:
58                     # 修改原密码
59                     user_obj.set_password(dic["new_pwd"])
60                     user_obj.save()
61                     return redirect('/login/')
62             else:
63                 return HttpResponse("原密码错误")
64     form_obj = froms.SetPwdForm()
65     return render(request, 'set_pwd.html', {'form_obj': form_obj, })
66 
67 
68 def logout(request):
69     auth.logout(request)
70     return redirect("/login/")
views.py
 1 from django import forms
 2 
 3 
 4 class RegForm(forms.Form):
 5     username = forms.CharField(
 6         min_length=3,
 7         label='用户名',
 8         error_messages={
 9             'required': '用户名不能为空',
10             'min_length': '用户名最少不能少于三个字符',
11         },
12         widget=forms.widgets.TextInput(attrs={'class': 'form-control', })
13     )
14     password = forms.CharField(
15         min_length=6,
16         label='密码',
17         error_messages={
18             'required': '密码不能为空',
19             'min_length': '密码不能少于6位数',
20         },
21         widget=forms.widgets.PasswordInput(attrs={'class': 'form-control', })
22     )
23     con_pwd = forms.CharField(
24         min_length=6,
25         label='确认密码',
26         error_messages={
27             'required': '密码不能为空',
28             'min_length': '密码不能少于6位数',
29         },
30         widget=forms.widgets.PasswordInput(attrs={'class': 'form-control', })
31     )
32 
33 
34 class LoginForm(forms.Form):
35     username = forms.CharField(
36         min_length=3,
37         label='用户名',
38         error_messages={
39             'required': '用户名不能为空',
40             'min_length': '用户名最少不能少于三个字符',
41         },
42         widget=forms.widgets.TextInput(attrs={'class': 'form-control', })
43     )
44     password = forms.CharField(
45         min_length=6,
46         label='密码',
47         error_messages={
48             'required': '密码不能为空',
49             'min_length': '密码不能少于6位数',
50         },
51         widget=forms.widgets.PasswordInput(attrs={'class': 'form-control', })
52     )
53 
54 
55 class SetPwdForm(forms.Form):
56     old_pwd = forms.CharField(
57         min_length=6,
58         label='原密码',
59         error_messages={
60             'required': '密码不能为空',
61             'min_length': '密码不能少于6位数',
62         },
63         widget=forms.widgets.PasswordInput(attrs={'class': 'form-control', })
64     )
65     new_pwd = forms.CharField(
66         min_length=6,
67         label='新密码',
68         error_messages={
69             'required': '密码不能为空',
70             'min_length': '密码不能少于6位数',
71         },
72         widget=forms.widgets.PasswordInput(attrs={'class': 'form-control', })
73     )
74     con_pwd = forms.CharField(
75         min_length=6,
76         label='确认密码',
77         error_messages={
78             'required': '密码不能为空',
79             'min_length': '密码不能少于6位数',
80         },
81         widget=forms.widgets.PasswordInput(attrs={'class': 'form-control', })
82     )
froms.py
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1">
 6     <title>注册</title>
 7     <link rel="stylesheet" href="../static/bootstrap-3.3.7/css/bootstrap.min.css">
 8     <style type="text/css">
 9         .top{
10             margin-top: 5%;
11         }
12     </style>
13 </head>
14 <body>
15 <div class="container-fluid">
16     <div class="row">
17         <div class="top col-md-4 col-md-offset-4">
18             <div class="panel panel-danger">
19             <div class="panel-heading">
20                 <h3 class="panel-title"><strong>欢迎注册</strong></h3>
21             </div>
22             <div class="panel-body">
23                 <form action="" method="post" novalidate autocomplete="off">
24                     {% csrf_token %}
25                     <div class="form-group">
26                         <label for="{{ form_obj.username.id_for_label }}">{{ form_obj.username.label }}</label>
27                         {{ form_obj.username }}
28                         <span class="help-block">{{ form_obj.username.errors.0 }}</span>
29                     </div>
30                     <div class="form-group">
31                         <label for="{{ form_obj.password.id_for_label }}">{{ form_obj.password.label }}</label>
32                         {{ form_obj.password }}
33                         <span class="help-block">{{ form_obj.password.errors.0 }}</span>
34                     </div>
35                     <div class="form-group">
36                         <label for="{{ form_obj.con_pwd.id_for_label }}">{{ form_obj.con_pwd.label }}</label>
37                         {{ form_obj.con_pwd }}
38                         <span class="help-block">{{ form_obj.con_pwd.errors.0 }}</span>
39                     </div>
40                     <button type="submit" class="btn btn-default btn-block">注册</button>
41                 </form>
42             </div>
43         </div>
44         </div>
45     </div>
46 </div>
47 </body>
48 </html>
register.html
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1">
 6     <title>登录</title>
 7     <link rel="stylesheet" href="../static/bootstrap-3.3.7/css/bootstrap.min.css">
 8     <style type="text/css">
 9         .top{
10             margin-top: 5%;
11         }
12     </style>
13 </head>
14 <body>
15 <div class="container-fluid">
16     <div class="row">
17         <div class="top col-md-4 col-md-offset-4">
18             <div class="panel panel-primary">
19             <div class="panel-heading">
20                 <h3 class="panel-title"><strong>欢迎登录</strong></h3>
21             </div>
22             <div class="panel-body">
23                 <form action="" method="post" novalidate autocomplete="off">
24                     {% csrf_token %}
25                     <div class="form-group">
26                         <label for="{{ form_obj.username.id_for_label }}">{{ form_obj.username.label }}</label>
27                         {{ form_obj.username }}
28                         <span class="help-block">{{ form_obj.username.errors.0 }}</span>
29                     </div>
30                     <div class="form-group">
31                         <label for="{{ form_obj.password.id_for_label }}">{{ form_obj.password.label }}</label>
32                         {{ form_obj.password }}
33                         <span class="help-block">{{ form_obj.password.errors.0 }}</span>
34                     </div>
35                     <button type="submit" class="btn btn-default btn-block">登录</button>
36                 </form>
37             </div>
38         </div>
39         </div>
40     </div>
41 </div>
42 </body>
43 </html>
login.html
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1">
 6     <title>home</title>
 7 
 8 </head>
 9 <body>
10 <h1>你好,用户{{ request.user.username }}</h1>
11 <a href="/logout/">注销</a>
12 <a href="/set_pwd/">修改密码</a>
13 </body>
14 </html>
home.html
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1">
 6     <title>重置密码</title>
 7     <link rel="stylesheet" href="../static/bootstrap-3.3.7/css/bootstrap.min.css">
 8     <style type="text/css">
 9         .top{
10             margin-top: 5%;
11         }
12     </style>
13 </head>
14 <body>
15 <div class="container-fluid">
16     <div class="row">
17         <div class="top col-md-4 col-md-offset-4">
18             <div class="panel panel-danger">
19             <div class="panel-heading">
20                 <h3 class="panel-title"><strong>重置密码</strong></h3>
21             </div>
22             <div class="panel-body">
23                 <form action="" method="post" novalidate autocomplete="off">
24                     {% csrf_token %}
25                     <div class="form-group">
26                         <label for="{{ form_obj.old_pwd.id_for_label }}">{{ form_obj.old_pwd.label }}</label>
27                         {{ form_obj.old_pwd }}
28                         <span class="help-block">{{ form_obj.old_pwd.errors.0 }}</span>
29                     </div>
30                     <div class="form-group">
31                         <label for="{{ form_obj.new_pwd.id_for_label }}">{{ form_obj.new_pwd.label }}</label>
32                         {{ form_obj.new_pwd }}
33                         <span class="help-block">{{ form_obj.new_pwd.errors.0 }}</span>
34                     </div>
35                     <div class="form-group">
36                         <label for="{{ form_obj.con_pwd.id_for_label }}">{{ form_obj.con_pwd.label }}</label>
37                         {{ form_obj.con_pwd }}
38                         <span class="help-block">{{ form_obj.con_pwd.errors.0 }}</span>
39                     </div>
40                     <button type="submit" class="btn btn-default btn-block">确认</button>
41                 </form>
42             </div>
43         </div>
44         </div>
45     </div>
46 </div>
47 </body>
48 </html>
set_pwd.html

 

posted @ 2018-06-29 19:53  桥前石头  阅读(1531)  评论(0编辑  收藏  举报