前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >高阶应用-用户验证

高阶应用-用户验证

作者头像
星哥玩云
发布2022-09-14 17:42:34
8310
发布2022-09-14 17:42:34
举报
文章被收录于专栏:开源部署

一、说明

User是auth模块中维护用户信息的关系模式(继承了models.Model), 数据库中该表被命名为auth_user

二、User表的SQL描述

代码语言:javascript
复制
CREATE TABLE "auth_user" (
    "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, 
    "password" varchar(128) NOT NULL, "last_login" datetime NULL, 
    "is_superuser" bool NOT NULL, 
    "first_name" varchar(30) NOT NULL, 
    "last_name" varchar(30) NOT NULL,
    "email" varchar(254) NOT NULL, 
    "is_staff" bool NOT NULL, 
    "is_active" bool NOT NULL,
    "date_joined" datetime NOT NULL,
    "username" varchar(30) NOT NULL UNIQUE
)

导入

代码语言:javascript
复制
<span class="hljs-keyword">from</span> django.contrib.auth.models <span class="hljs-keyword">import</span> User

三、用户模型属性方法

is_staff

Boolean。决定用户是否可以访问admin管理界面。默认False

is_active

Boolean。 用户是否活跃,默认True。一般不删除用户,而是将用户的is_active设为False

is_authenticated()

用户是否通过验证,登陆

request.user.is_authenticated() 可以判断当前用户是否登录

登录则为 True 否则为False

make_password(password)

给密码加密 django自带的加密功能是hash 加盐

check_password(password)

检查用户输入的密码是否正确

set_password(password)

修改用户密码

authenticate() 认证用户名和密码是否正确

authenticate(username=username, password=password)

使用

代码语言:javascript
复制
<span class="hljs-keyword">from</span> django.contrib.auth <span class="hljs-keyword">import</span> authenticate

create_user() 创建用户

使用系统User模型

代码语言:javascript
复制
<span class="hljs-keyword">from</span> django.contrib.auth.models <span class="hljs-keyword">import</span> User
User.objects.create_user(username, email, password)

request.user 获取当前登录用户对象

request.user.username 获取当前登录用户的用户名

last_login 自动保存 不需要自己添加代码

上一次的登录时间,为datetime对象,默认为当时的时间。

user.last_login = timezone.now()

request.user.username

获取当前登录用户的用户名

login_required 设置视图函数必须登录才允许访问

代码语言:javascript
复制
<span class="hljs-keyword">from</span> django.contrib.auth.decorators <span class="hljs-keyword">import</span> login_required
<span class="hljs-meta">@login_required(login_url='/')  # 没有登录则跳转到首页</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">center</span><span class="hljs-params">(request)</span>:</span>
    <span class="hljs-keyword">return</span> Httpresponse(<span class="hljs-string">'个人中心'</span>)

login 登录

logout 退出登录

四、注册

模板 register.html

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
    <title>注册页面</title>
<style>
        .pg_header{
            position: fixed;
            height: 48px;
            top: 0;
            left: 0;
            right: 0;
            background-color: #2459a2;
            line-height: 48px;
        }
        .pg_header .logo{
            margin: 0 auto;
            float: left;
            width: 200px;
            text-align: center;
            line-height: 48px;
            font-size: 28px;
            color: white;
        }
        .pg_dl{
            left: 400px;
            display: inline-block;
            padding: 0 40px;
            color: white;
        }
        .pg_header .pg_dl:hover{
            background-color: #2459fb;
            cursor: pointer;
        }
        .left{
            margin-top: 20px;
            width: 400px;
            display: inline-block;
            float: left;
        }
        .pg_body{
            margin-top: 50px;
            font-size: 18px;
            display: inline-block;
            width: 200px;
        }
        .pg_body .menu{
            width: 800px;
            padding: 15px;
            float: left;
            font-weight: bold;
        }
        input[type="text"]{
            width: 200px;
            height: 25px;
            border-radius: 6px;
        }
        input[type="password"]{
            width: 200px;
            height: 25px;
            border-radius: 6px;
        }
        input[type="button"]{
            background-color: #555555;
               border: none;
            color: white;
            padding: 12px 29px;
            text-align: center;
            text-decoration: none;
            display: inline-block;
            font-size: 17px;
            margin: 4px 2px;
            cursor: pointer;
            border-radius: 4px;
        }
        input[type="submit"]{
            background-color: #555555;
               border: none;
            color: white;
            padding: 12px 29px;
            text-align: center;
            text-decoration: none;
            display: inline-block;
            font-size: 17px;
            margin: 4px 2px;
            cursor: pointer;
            border-radius: 4px;
        }
        .kong{
            margin-top: -54px;
            margin-left: 200px;
            float:left;
            padding: 15px;
        }
        .img{
            width: 50px;
            height: 40px;
        }
        .can{
            width: 1220px;
            height: 40px;
            line-height: 40px;
            margin: 0 auto;
            text-align: center;
            display: inline-block;
        }
        .tian{
            color: red;
            float: right;
            font-size: 12px;
            margin-right: -120px;
            margin-top: -25px;
        }
    </style>
</head>
<body id="i88" style="margin: 0">
    <div class = "pg_header">
        <a class = "logo">LOGO</a>
        <a class="pg_dl" id="i77">注册</a>
    </div>
    <form name="tijiao" method="post" onsubmit="return check()" action="{% url 'App:register' %}">
        {% csrf_token %}
        <div class="left"></div>
        <div class="pg_body">
                <div class="menu">用户名:</div>
                    <div class="kong">
                        <input id="text1" type="text" name="username" placeholder="请输入用户名" onblur="check()"><span id="div1" class="tian" style="margin-top: 4px">*(为必填)</span>
                    </div>

                <div class="menu">密码:</div>
                    <div class="kong">
                        <input id="text2" type="password" name="userpass" onblur="check()">
                        <span id="div2" class="tian" style="margin-top: 5px">*(为必填)</span>
                    </div>
                <div class="menu">确认密码:</div>
                    <div class="kong">
                        <input id="text3" type="password" name="01" onblur="check()">
                        <span id="div3" class="tian" style="margin-top: 5px">*(为必填)</span>
                    </div>
                <div class="menu">邮箱地址:</div>
                    <div class="kong">
                        <input id="text4" type="text" name="email" onblur="check()" required>
                        <span id="div4" class="tian" style="margin-top: 5px">*(为必填)</span>
                    </div>
        </div>
        <div class="can">
            <input id="i111" type="submit" name="002" value="注  册">
            <p style="width: 200px;display: inline-block;"></p>
            <input id="i222" type="button" name="004" value="取  消">
        </div>
    </form>
    <script type="text/javascript">
            //刷新or取消
            document.getElementById('i77').onclick = function(){
                location.reload();
            }
            document.getElementById('i222').onclick = function(){
                location.reload();
            }

            //用户名验证
            function checkname(){
                var div = document.getElementById("div1");
                div.innerHTML = "";
                var name1 = document.tijiao.text1.value;
                if (name1 == "") {
                div.innerHTML = "用户名不能为空!";
                document.tijiao.text1.focus();
                return false;
            }
                if (name1.length < 4 || name1.length > 16) {
                div.innerHTML = "长度4-16个字符";
                document.tijiao.text1.select();
                return false;
            }
                var charname1 = name1.toLowerCase();
                for (var i = 0; i < name1.length; i++) {
                var charname = charname1.charAt(i);
                if (!(charname >= 0 && charname <= 9) && (!(charname >= 'a' && charname <= 'z')) && (charname != '_')) {
                    div.innerHTML = "用户名包含非法字符";
                    document.form1.text1.select();
                    return false;
                }
            }
                return true;
        }

            //密码验证
            function checkpassword(){
                var div = document.getElementById("div2");
                div.innerHTML = "";
                var password = document.tijiao.text2.value;
                if (password == "") {
                div.innerHTML = "密码不能为空";
                {#document.tijao.text2.focus();#}
                return false;
            }
                if (password.length < 4 || password.length > 16) {
                div.innerHTML = "密码长度为4-16位";
                document.tijiao.text2.select();
                return false;
                }
                return true;
        }

            function checkrepassword(){
                var div = document.getElementById("div3");
                div.innerHTML = "";
                var password = document.tijiao.text2.value;
                var repass = document.tijiao.text3.value;
                if (repass == "") {
                div.innerHTML = "密码不能为空";
                document.tijiao.text3.focus();
                return false;
                }
                if (password != repass) {
                div.innerHTML = "密码不一致";
                document.tijiao.text3.select();
                return false;
                }
                return true;
            }
        //邮箱验证
        function checkEmail(){
            var div = document.getElementById("div4");
            div.innerHTML = "";
            var email = document.tijiao.text4.value;
            var sw = email.indexOf("@", 0);
            var sw1 = email.indexOf(".", 0);
            var tt = sw1 - sw;
            if (email.length == 0) {
            div.innerHTML = "邮箱不能为空";
            document.tijiao.text5.focus();
            return false;
            }

            if (email.indexOf("@", 0) == -1) {
            div.innerHTML = "必须包含@符号";
            document.tijiao.text5.select();
            return false;
            }

            if (email.indexOf(".", 0) == -1) {
            div.innerHTML = "必须包含.符号";
            document.tijiao.text5.select();
            return false;
            }

            if (tt == 1) {
                div.innerHTML = "@和.不能一起";
                document.tijiao.text5.select();
                return false;
            }

            if (sw > sw1) {
                div.innerHTML  = "@符号必须在.之前";
                document.tijiao.text5.select();
                return false;
            }
            else {
                return true;
            }
            return ture;
            }

            function check(){
            if (checkname() && checkpassword() && checkrepassword() && checkEmail()) {
            return true;
            }
            else {
            return false;
        }
    }
    </script>
</body>
</html>

views.py

代码语言:javascript
复制
<span class="hljs-keyword">from</span> django.conf <span class="hljs-keyword">import</span> settings  <span class="hljs-comment"># 导入配置</span>
<span class="hljs-keyword">from</span> django.shortcuts <span class="hljs-keyword">import</span> render,HttpResponse,redirect,reverse
<span class="hljs-keyword">from</span> django.contrib.auth.models <span class="hljs-keyword">import</span> User  <span class="hljs-comment"># 导入系统User模型</span>
<span class="hljs-keyword">from</span> django.contrib.auth <span class="hljs-keyword">import</span> login,authenticate

<span class="hljs-comment"># 使用系统用户模型 以及方法 进行登录注册 退出登录等处理</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">register</span><span class="hljs-params">(req)</span>:</span>
    <span class="hljs-keyword">if</span> req.method == <span class="hljs-string">'POST'</span>:
        <span class="hljs-comment"># 接受表单传递过来的数据</span>
        username = req.POST.get(<span class="hljs-string">'username'</span>)
        userpass = req.POST.get(<span class="hljs-string">'userpass'</span>)
        email = req.POST.get(<span class="hljs-string">'email'</span>)
        <span class="hljs-keyword">try</span>:
            <span class="hljs-comment"># 用户的创建</span>
        User.objects.create_user(username,email,userpass)
        <span class="hljs-keyword">except</span>:
            <span class="hljs-keyword">return</span> HttpResponse(<span class="hljs-string">'注册失败'</span>)
        <span class="hljs-keyword">return</span> HttpResponse(<span class="hljs-string">'注册成功'</span>)
    <span class="hljs-keyword">return</span> render(req,<span class="hljs-string">'register.html'</span>)

五、认证用户

导入

代码语言:javascript
复制
<span class="hljs-keyword">from</span> django.contrib.auth <span class="hljs-keyword">import</span> login,authenticate

login 处理用户登录状态的方法

authenticate 认证用户的用户名和密码是否正确 正确返回用户对象 否则None

视图函数

代码语言:javascript
复制
<span class="hljs-keyword">from</span> django.conf <span class="hljs-keyword">import</span> settings  <span class="hljs-comment"># 导入配置</span>
<span class="hljs-keyword">from</span> django.shortcuts <span class="hljs-keyword">import</span> render,HttpResponse,redirect,reverse
<span class="hljs-keyword">from</span> django.contrib.auth.models <span class="hljs-keyword">import</span> User  <span class="hljs-comment"># 导入系统User模型</span>
<span class="hljs-keyword">from</span> django.contrib.auth <span class="hljs-keyword">import</span> login,authenticate


<span class="hljs-comment"># 用户认证 登录</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">Login</span><span class="hljs-params">(req)</span>:</span>
    <span class="hljs-keyword">if</span> req.method == <span class="hljs-string">'POST'</span>:
        username = req.POST.get(<span class="hljs-string">'username'</span>)
        userpass = req.POST.get(<span class="hljs-string">'userpass'</span>)
        user = authenticate(username=username,password=userpass)
        <span class="hljs-comment"># 认证成功返回对象 否则None</span>
        <span class="hljs-keyword">if</span> user:
            <span class="hljs-comment"># 处理登录状态的维持</span>
            login(req,user)
            <span class="hljs-comment"># 重定向到首页</span>
            <span class="hljs-keyword">return</span> redirect(reverse(<span class="hljs-string">'App:index'</span>))
        <span class="hljs-keyword">else</span>:
            <span class="hljs-keyword">return</span> redirect(reverse(<span class="hljs-string">'App:Login'</span>))
    <span class="hljs-keyword">return</span> render(req,<span class="hljs-string">'login.html'</span>)

注意:如果该用户is_active为False 则认证失败

在模板中判断是否登录

Django自带的用户认证授权系统

如果用户已经授权成功,说明用户已经登录成功,那么在渲染index.html的时候,直接展示已登录状态即可;如果用户认证失败,说明没有登录,那么在渲染index.html的时候,直接展示登录表单即可

代码语言:javascript
复制
{% if request.user.is_authenticated %}
    <h3>登录了欢迎{{ request.user.username }}</h3>
{% else %}
    <h3>没登录</h3>
{% endif %} 

六、修改用户密码

方法

set_password(new_password)

说明

修改密码是User的实例方法, 该方法不验证用户身份

代码语言:javascript
复制
user.set_password(new_password)

通常该方法需要和authenticate配合使用

代码语言:javascript
复制
user = auth.authenticate(username=username, password=old_password)
<span class="hljs-keyword">if</span> user <span class="hljs-keyword">is</span> <span class="hljs-keyword">not</span> <span class="hljs-keyword">None</span>:
    user.set_password(new_password)
    user.save()

七、视图函数获取登录用户对象

代码语言:javascript
复制
<span class="hljs-comment"># 在视图函数中获取登录用户的数据</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">own</span><span class="hljs-params">(req)</span>:</span>
    <span class="hljs-comment"># 判断是否登录</span>
    <span class="hljs-keyword">if</span> req.user.is_authenticated:
        print(req.user.username) <span class="hljs-comment"># 获取登录的用户名</span>
        print(req.user.last_login)  <span class="hljs-comment"># 上次登录时间</span>
    <span class="hljs-keyword">return</span> HttpResponse(<span class="hljs-string">'在视图函数中获取登录用户的数据'</span>)

八、退出登录

logout会移除request中的user信息, 并刷新session

代码语言:javascript
复制
<span class="hljs-keyword">from</span> django.contrib.auth <span class="hljs-keyword">import</span> logout

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">logout_view</span><span class="hljs-params">(request)</span>:</span>
    logout(request)
    <span class="hljs-keyword">return</span> redirect(reverse(<span class="hljs-string">'App:index'</span>))

九、权限判断(只允许登录用户访问)

@login_required修饰器修饰的view函数会先通过session key检查是否登录, 已登录用户可以正常的执行操作, 未登录用户将被重定向到login_url指定的位置。若未指定login_url参数, 则重定向到settings.LOGIN_URL

代码语言:javascript
复制
<span class="hljs-comment"># 在视图函数中获取登录用户的数据</span>
<span class="hljs-comment"># 当前的own视图函数 必须登录才能访问</span>
<span class="hljs-comment"># @login_required(login_url='/system_login/')</span>
<span class="hljs-meta">@login_required  # 没有指定login_url 则会重定向到settings.py中指定的LOGIN_URL的路由地址</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">own</span><span class="hljs-params">(req)</span>:</span>
    <span class="hljs-comment"># 判断是否登录</span>
    <span class="hljs-keyword">if</span> req.user.is_authenticated:
        print(req.user.username) <span class="hljs-comment"># 获取登录的用户名</span>
        print(req.user.last_login)  <span class="hljs-comment"># 上次登录时间</span>
    <span class="hljs-keyword">return</span> HttpResponse(<span class="hljs-string">'在视图函数中获取登录用户的数据'</span>)

配置全局 就不用再每一个装饰器添加了

settings.py

LOGIN_URL = ‘/login/’

十、自定义用户表

给auth_user的模型表添加新字段 iphon和icon字段

models.py

代码语言:javascript
复制
<span class="hljs-keyword">from</span> django.contrib.auth.models <span class="hljs-keyword">import</span> AbstractUser

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span><span class="hljs-params">(AbstractUser)</span>:</span>
    iphone = models.CharField(max_length=<span class="hljs-number">11</span>,default=<span class="hljs-number">15611833906</span>)
    icon = models.CharField(max_length=<span class="hljs-number">40</span>,default=<span class="hljs-string">'default.jpg'</span>)

将用户模型设置为自己的模型

代码语言:javascript
复制
AUTH_USER_MODEL = <span class="hljs-string">'App.User'</span>

将迁移文件 和 库删除 在重新执行迁移

添加自定义用户认证

在App下新建一个auth.py

auth.py

代码语言:javascript
复制
<span class="hljs-keyword">from</span> django.contrib.auth.backends <span class="hljs-keyword">import</span> ModelBackend
<span class="hljs-keyword">from</span> django.db.models <span class="hljs-keyword">import</span> Q

<span class="hljs-keyword">from</span> App.models <span class="hljs-keyword">import</span> User


<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyBackend</span><span class="hljs-params">(ModelBackend)</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">authenticate</span><span class="hljs-params">(self, username=None, password=None, **kwargs)</span>:</span>
        user = User.objects.filter(Q(username=username)|Q(iphone=username)|Q(email=username)).first()
        <span class="hljs-keyword">if</span> user:
            <span class="hljs-keyword">if</span> user.check_password(password):
                <span class="hljs-keyword">return</span> user
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">None</span>

注意:

当认证失败的时候返回值只能为None否则报错

在settings.py添加如下代码

代码语言:javascript
复制
AUTHENTICATION_BACKENDS = (
    <span class="hljs-string">'App.auth.MyBackend'</span>,
)

视图代码更改为

代码语言:javascript
复制
<span class="hljs-keyword">from</span> App.models <span class="hljs-keyword">import</span> User
u = User.objects.create_user(username,email,userpass,iphone=<span class="hljs-string">'18826123687'</span>)
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、说明
  • 二、User表的SQL描述
  • 三、用户模型属性方法
  • 四、注册
  • 五、认证用户
  • 六、修改用户密码
  • 七、视图函数获取登录用户对象
  • 八、退出登录
  • 九、权限判断(只允许登录用户访问)
  • 十、自定义用户表
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档