Django 实战2:利用 Session 实现自动登录机制

题图:by thefolkpr0ject from Instagram

上篇文章中讲到 Django 如何启动以及配置 sessions 功能。sessions 功能用是跟踪用户的状态,经常结合 Cookie 功能实现自动登录功能。 所谓的“自动登录”指的是:我们登录一些网站,在不关闭浏览器以及距离上次登录时间不是很长的情况下。无论我们在新的标签页打开网站,还是关闭页面重新打开网站,登录状态一直保持着。本文内容有两个:一是利用 Django 实现自动登录功能,二是揭开“自动登录”的神秘面纱。

1 新建项目

我为了将本系列所有文章的示例代码保持集中状态,所以直接在 Django_demo 项目中创建应用。如果第一次看这文章,需要先创建项目(project),再创建应用(app)。我新建的应用是 demo_session

然后在 setting.py 中启动请用,并检查 sessions 组件是否启动。

因为需要 Cookie 功能,所以同样需要在 settings.py 增加一些配置。

SESSION_COOKIE_NAME = "sessionid"       # Session的cookie保存在浏览器上时的key
SESSION_COOKIE_PATH = "/"               # Session的cookie保存的路径(默认)
SESSION_COOKIE_DOMAIN = None            # Session的cookie保存的域名(默认)
SESSION_COOKIE_SECURE = False           # 是否Https传输cookie
SESSION_COOKIE_HTTPONLY = True          # 是否Session的cookie只支持http传输(默认)
SESSION_COOKIE_AGE = 1209600            # Session的cookie失效日期(2周)(默认)
SESSION_SAVE_EVERY_REQUEST = False      # 是否设置关闭浏览器使得Session过期
SESSION_COOKIE_AT_BROWSER_CLOSE = False  # 是否每次请求都保存Session,默认修改之后才能保存

如果你将 SESSION_SAVE_EVERY_REQUEST 设置为 True, 那么关闭浏览器之后,需要重新登录。

2 流程

应用中会涉及到 3 个页面,所以我绘制流程图帮助理解。

3 实现

3.1 新建 model

服务器接收到浏览器传送过来登录信息,需要验证账号和密码等信息。所以需要新建 model 保存信息,以便后续跟数据库做校验。这里我只是简单保存信息,登录验证后续讲解。

class User(models.Model):
    username = models.CharField(max_length=20)  # 账号
    password = models.CharField(max_length=20)  # 密码
    nickname = models.CharField(max_length=20)  # 昵称

3.2 新建 form

用户将登录信息发送给服务器是用到 POST 请求,所以需要创建表单。在应用目录下新建名为 forms 目录,然后创建 forms.py 文件。

from django.forms import ModelForm, TextInput, PasswordInput
from demo_session.models import User

class UserForm(ModelForm):
    class Meta:
        model = User
        fields = ['username', 'password', ]  # 只显示 model 中指定的字段
        # 指定呈现样式字段、指定 CSS 样式
        widgets = {
            'username': TextInput(attrs={'class': 'text',
                                         'value': 'monkey'}),
            'password': PasswordInput(attrs={'value': '13245678', })
        }

3.3 新建视图

页面一共有三个,分别是登录、首页、登出。具体实现如下:

# view.py
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render
from demo_session.form.forms import UserForm

# 用户登录
def login_view(request):
    # 过滤 POST 方法的请求
    if request.method == 'POST':
        userfrom = UserForm(request.POST)
        # 验证表单
        if userfrom.is_valid():
            username = userfrom.cleaned_data['username']
            password = userfrom.cleaned_data['password']
            # ... 执行验证登录信息操作

            # 将等你信息传递给 Session 对象, 实际应用中不建议这么操作
            request.session['username'] = username
            # 跳转到页面
            return HttpResponseRedirect('/index/')
    else:
        # 不是 GET 请求则显示表单
        userfrom = UserForm()
    template_view = 'login.html'
    return render(request, template_view, {'userfrom': userfrom})

# 成功登录之后, 跳转首页
def index_view(request):
    username = request.session.get('username', '')
    # print(username)
    template_view = 'index.html'
    return render(request, template_view, {'username': username})

# 登出操作
def logout_view(request):
    # 删除 session
    del request.session['username']
    return HttpResponse('登出成功')

3.4 对应模板

视图 login_view, index_view 对应的模板是 login.html, index.html。 其中 login.html 的实现如下:

{% load staticfiles %}
<!DOCTYPE html>
<html lang="{{ LANGUAGE_CODE|default:"en-us" }}">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
    <link href="{% static 'css/style.css' %}" rel="stylesheet" type='text/css' >
    <!--webfonts-->
    <link href="{% static 'css/font.css' %}" rel='stylesheet' type='text/css'>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script type="application/x-javascript">
            addEventListener("load", function() { setTimeout(hideURLbar, 0); }, false);
            function hideURLbar(){ window.scrollTo(0,1); }</script>
</head>
<body>
    <div class="main">
        <div class="login-form">
        <h1>Member Login</h1>
            <div class="head">
                <img src="{% static 'images/user.png' %}" alt=""/>
            </div>
            <form action="" method="POST">
                {% csrf_token %}
                {{ userfrom.username }}
                {{ userfrom.password }}
                <div class="submit"><input type="submit" value="login" ></div>
                <p><a href="#">Forgot Password ?</a></p>
            </form>
        </div>
    </div>
</body>
</html>

index.html 的实现如下:

<!DOCTYPE html>
<html lang="{{ LANGUAGE_CODE|default:"en-us" }}">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
    <div >
        <h3>欢迎 {{username}} 到来~</h3>
        <div class="submit"><a href="/logout"><input type="submit" value="退出登录" ></a></div>
    </div>
</body>
</html>

3.5 配置路由

最后一步,在 urls.py 中配置访问路径:

from demo_session.views import login_view, index_view, logout_view

urlpatterns = [
    # demo_session
    path('login/', login_view, name='login'),
    path('index/', index_view, name='index'),
    path('logout/', logout_view, name='index'),
]

4 实现效果

用户访问 http://127.0.0.1/login 进行登录操作。

当点击 login 成功之后,会跳转到首页,首页会显示用户名。同时,Cookie 中多了一个 sessionid 的字段。这字段名就是我们在 setttings.py 定义的。

查询数据库 django_session 表的内容,会多出一条数据。

表中的字段含义如下:

  • session_key: 就是服务器给用户返回的id。在浏览器当中,这个值是保存为sessionid
  • session_data: 这是一个加密后的信息,用来保存用户名和密码等信息
  • expire_data: 过期时间,Django可以设置过期时间

在新的标签页中打开首页,依然能看到 username 信息。这证明能自动登录。

如果用户退出登录,再访问首页。这时会发现看不到了 username 信息了。

5 小结

实现自动登录功能其实不难,只需要在 Django 的 Sessions 组件。然后根据场景需要,在 settings.py 配置 session 以及 cookie 等信息。

END

不积跬步,无以至千里

原文发布于微信公众号 - 极客猴(Geek_monkey)

原文发表时间:2018-05-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏blackheart的专栏

[OIDC in Action] 1. 基于OIDC(OpenID Connect)的SSO

在[认证授权]系列博客中,分别对OAuth2和OIDC在理论概念方面进行了解释说明,其间虽然我有写过一个完整的示例(https://github.com/lin...

39010
来自专栏13blog.site

Plugin 'Lombok Plugin' is incompatible with this installation

Plugin 'Lombok Plugin' is incompatible with this installation

1072
来自专栏yukong的小专栏

【ssm个人博客项目实战09】写博客与自定义监听器1、2、3、

前面我们已经完成了博客的分页显示模糊查询删除等功能,现在我们就讲一下如何实现写博客与修改博客的功能。

1233
来自专栏软件测试经验与教训

LR录制要点

3155
来自专栏开发与安全

有关Web 安全学习的片段记录(不定时更新)

很多Web 安全漏洞的产生原因都绕不开两条: 1.违背了“数据与代码分离“原则。它有两个条件:一是用户能够控制数据的输入;二是代码拼凑了用户输入的数据,把数据当...

2090
来自专栏分布式系统进阶

Kafka重置消费的OffsetKafka源码分析-汇总

5182
来自专栏linux、Python学习

Linux基础教程之linux文件权限深度解读

基本命令—— 1.cut : cat /etc/passwd | cut -d’:’ -f7| uniq -c| sort -nr

850
来自专栏along的开发之旅

windows下安装调教ubuntu 17.10步骤

安装ubuntu好多次了, 每次安装都有一些重复步骤要走, 但是这些步骤又比较细, 不用的时间一长就忘记了, 所以在这里单独记录一下, 省的每次都要google...

802
来自专栏云计算教程系列

使用CVM搭建FileRun私人网盘

FileRun是由PHP编写的文件管理器和文件共享程序,可帮助您访问,整理,查看和编辑文件。您可以将其与Office文档,照片,音乐等文件一起使用。在本教程中,...

45411
来自专栏散尽浮华

进程管理利器-supervisor部署记录

一、简单介绍 supervisor是用来管理进程的一个工具,止于为什么要用supervisor,是因为相对于linux传统的进程管理方式来说,它有很多的优势: ...

3948

扫码关注云+社区

领取腾讯云代金券