django-利用session机制实现唯一登录的例子

配置连接数据库

DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME': '数据库名称',
    'USER': 'root',
    'PASSWORD': '123456',
    'HOST': '10.18.62.2',
    'PORT': '3306',
  }
}

生成session表

python manage.py makemigrations
python manage.py migrate

登录时记住保存用户登录信息

# 登录验证
def login_ver(request):
  if request.method == 'POST':
    username = request.POST.get('username')
    password = request.POST.get('password')
    '''
    # 用前端输入的用户名,密码去数据库里找到用户的信息
    user=数据库(username,password)
    '''
    # 数据库中得有一张users表
    user = list(Users.objects.filter(username=username,password=password).values())
    # 用户信息记录在session中
    request.session['user'] = user
    # 创建session,否则key为None
    if not request.session.session_key:
      request.session.create()
    # 获取session_key
      key = request.session.session_key
    # 当另一机器登录时,本机器应该被挤下即当前sessionkey失效,后登录的用户的session可用,之前的sessionkey从数据库中删除
    # 获取指定key的session_data,下面用的ORM模型去数据库中取数据
    session_data = list(DjangoSession.objects.filter(session_key=key).values_list('session_data'))[0][0]
    # 删除key不为当前key,session_data等于当前session_data的session记录,从而达到一个账号只能一台机器登录的目的
    models.DjangoSession.objects.filter(session_data=session_data).exclude(session_key=key).delete()

补充知识:Django 用Session和Cookie分别实现记住用户登录状态

简介

由于http协议的请求是无状态的。故为了让用户在浏览器中再次访问该服务端时,他的登录状态能够保留(也可翻译为该用户访问这个服务端其他网页时不需再重复进行用户认证)。我们可以采用Cookie或Session这两种方式来让浏览器记住用户。

Cookie与Session说明与实现

Cookie

说明

Cookie是一段小信息(数据格式一般是类似key-value的键值对),由服务器生成,并发送给浏览器让浏览器保存(保存时间由服务端定夺)。当浏览器下次访问该服务端时,会将它保存的Cookie再发给服务器,从而让服务器根据Cookie知道是哪个浏览器或用户在访问它。(由于浏览器遵从的协议,它不会把该服务器的Cookie发送给另一个不同host的服务器)。

Django中实现Cookie

from django.shortcuts import render, redirect

# 设置cookie
"""
key: cookie的名字
value: cookie对应的值
max_age: cookie过期的时间
"""
response.set_cookie(key, value, max_age)
# 为了安全,有时候我们会调用下面的函数来给cookie加盐
response.set_signed_cookie(key,value,salt='加密盐',...)

# 获取cookie
request.COOKIES.get(key)
request.get_signed_cookie(key, salt="加密盐", default=None)

# 删除cookie
reponse.delete_cookie(key)

下面就是具体的代码实现了

views.py

# 编写装饰器检查用户是否登录
def check_login(func):
  def inner(request, *args, **kwargs):
    next_url = request.get_full_path()
    # 假设设置的cookie的key为login,value为yes
    if request.get_signed_cookie("login", salt="SSS", default=None) == 'yes':
      # 已经登录的用户,则放行
      return func(request, *args, **kwargs)
    else:
      # 没有登录的用户,跳转到登录页面
      return redirect(f"/login?next={next_url}")

  return inner

# 编写用户登录页面的控制函数
@csrf_exempt
def login(request):
  if request.method == "POST":
    username = request.POST.get("username")
    passwd = request.POST.get("password")
    next_url = request.POST.get("next_url")

    # 对用户进行验证,假设用户名为:aaa, 密码为123
    if username === 'aaa' and passwd == '123':
      # 执行其他逻辑操作,例如保存用户信息到数据库等
      # print(f'next_url={next_url}')
      # 登录成功后跳转,否则直接回到主页面
      if next_url and next_url != "/logout/":
        response = redirect(next_url)
      else:
        response = redirect("/index/")
      # 若登录成功,则设置cookie,加盐值可自己定义取,这里定义12小时后cookie过期
      response.set_signed_cookie("login", 'yes', salt="SSS", max_age=60*60*12)
      return response
    else:
      # 登录失败,则返回失败提示到登录页面
      error_msg = '登录验证失败,请重新尝试'
      return render(request, "app/login.html", {
        'login_error_msg': error_msg,
        'next_url': next_url,
      })
  # 用户刚进入登录页面时,获取到跳转链接,并保存
  next_url = request.GET.get("next", '')
  return render(request, "app/login.html", {
    'next_url': next_url
  })

# 登出页面
def logout(request):
  rep = redirect("/login/")
  # 删除用户浏览器上之前设置的cookie
  rep.delete_cookie('login')
  return rep

# 给主页添加登录权限认证
@check_login
def index(request):
  return render(request, "app/index.html")

由上面看出,其实就是在第一次用户登录成功时,设置cookie,用户访问其他页面时进行cookie验证,用户登出时删除cookie。

另外附上前端的login.html部分代码

     <form action="{% url 'login' %}" method="post">
       <h1>请使xx账户登录</h1>
       <div>
        <input id="user" type="text" class="form-control" name="username" placeholder="账户" required="" />
       </div>
       <div>
        <input id="pwd" type="password" class="form-control" name="password" placeholder="密码" required="" />
       </div>
        <div style="display: none;">
          <input id="next" type="text" name="next_url" value="{{ next_url }}" />
        </div>
        {% if login_error_msg %}
          <div id="error-msg">
            <span style="color: rgba(255,53,49,0.8); font-family: cursive;">{{ login_error_msg }}</span>
          </div>
        {% endif %}
       <div>
         <button type="submit" class="btn btn-default" style="float: initial; margin-left: 0px">登录</button>
       </div>
      </form>

Session

Session说明

Session则是为了保证用户信息的安全,将这些信息保存到服务端进行验证的一种方式。但它却依赖于cookie。具体的过程是:服务端给每个客户端(即浏览器)设置一个cookie(从上面的cookie我们知道,cookie是一种”key, value“形式的数据,这个cookie的value是服务端随机生成的一段但唯一的值)。

当客户端下次访问该服务端时,它将cookie传递给服务端,服务端得到cookie,根据该cookie的value去服务端的Session数据库中找到该value对应的用户信息。(Django中在应用的setting.py中配置Session数据库)。

根据以上描述,我们知道Session把用户的敏感信息都保存到了服务端数据库中,这样具有较高的安全性。

Django中Session的实现

# 设置session数据, key是字符串,value可以是任何值
request.session[key] = value
# 获取 session
request.session.get[key]
# 删除 session中的某个数据
del request.session[key]
# 清空session中的所有数据
request.session.delete()

下面就是具体的代码实现了:

首先就是设置保存session的数据库了。这个在setting.py中配置:(注意我这里数据库用的mongodb,并使用了django_mongoengine库;关于这个配置请根据自己使用的数据库进行选择,具体配置可参考官方教程)

SESSION_ENGINE = 'django_mongoengine.sessions'
SESSION_SERIALIZER = 'django_mongoengine.sessions.BSONSerializer'

views.py

# 编写装饰器检查用户是否登录
def check_login(func):
  def inner(request, *args, **kwargs):
    next_url = request.get_full_path()
    # 获取session判断用户是否已登录
    if request.session.get('is_login'):
      # 已经登录的用户...
      return func(request, *args, **kwargs)
    else:
      # 没有登录的用户,跳转刚到登录页面
      return redirect(f"/login?next={next_url}")

  return inner

@csrf_exempt
def login(request):
  if request.method == "POST":
    username = request.POST.get("username")
    passwd = request.POST.get("password")
    next_url = request.POST.get("next_url")
    # 若是有记住密码功能
    # remember_sign = request.POST.get("check_remember")
    # print(remember_sign)

    # 对用户进行验证
    if username == 'aaa' and passwd == '123':
      # 进行逻辑处理,比如保存用户与密码到数据库

      # 若要使用记住密码功能,可保存用户名、密码到session
      # request.session['user_info'] = {
        # 'username': username,
        # 'password': passwd
      # }
      request.session['is_login'] = True
      # 判断是否勾选了记住密码的复选框
      # if remember_sign == 'on':
      #  request.session['is_remember'] = True
      # else:
        # request.session['is_remember'] = False

      # print(f'next_url={next_url}')
      if next_url and next_url != "/logout/":
        response = redirect(next_url)
      else:
        response = redirect("/index/")
      return response
    else:
      error_msg = '登录验证失败,请重新尝试'
      return render(request, "app/login.html", {
        'login_error_msg': error_msg,
        'next_url': next_url,
      })
  next_url = request.GET.get("next", '')
  # 检查是否勾选了记住密码功能
  # password, check_value = '', ''
  # user_session = request.session.get('user_info', {})
  # username = user_session.get('username', '')
  # print(user_session)
  #if request.session.get('is_remember'):
  #  password = user_session.get('password', '')
  #  check_value = 'checked'
  # print(username, password)
  return render(request, "app/login.html", {
    'next_url': next_url,
    # 'user': username,
    # 'password': password,
    # 'check_value': check_value
  })

def logout(request):
  rep = redirect("/login/")
  # request.session.delete()
  # 登出,则删除掉session中的某条数据
  if 'is_login' in request.session:
    del request.session['is_login']
  return rep

@check_login
def index(request):
  return render(request, "autotest/index.html")

另附login.html部分代码:

      <form action="{% url 'login' %}" method="post">
       <h1>请使xxx账户登录</h1>
       <div>
        <input id="user" type="text" class="form-control" name="username" placeholder="用户" required="" value="{{ user }}" />
       </div>
       <div>
        <input id="pwd" type="password" class="form-control" name="password" placeholder="密码" required="" value="{{ password }}" />
       </div>
        <div style="display: none;">
          <input id="next" type="text" name="next_url" value="{{ next_url }}" />
        </div>
        {% if login_error_msg %}
          <div id="error-msg">
            <span style="color: rgba(255,53,49,0.8); font-family: cursive;">{{ login_error_msg }}</span>
          </div>
        {% endif %}
        // 若设置了记住密码功能
        // <div style="float: left">
        //   <input id="rmb-me" type="checkbox" name="check_remember" {{ check_value }}/>记住密码
        // </div>
       <div>
         <button type="submit" class="btn btn-default" style="float: initial; margin-right: 60px">登录</button>
       </div>
      </form>

总的来看,session也是利用了cookie,通过cookie生成的value的唯一性,从而在后端数据库session表中找到这value对应的数据。session的用法可以保存更多的用户信息,并使这些信息不易被暴露。

总结

session和cookie都能实现记住用户登录状态的功能,如果为了安全起见,还是使用session更合适

以上这篇django-利用session机制实现唯一登录的例子就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Django中使用session保持用户登陆连接的例子

    使用session保持用户登陆连接 在 view 中 login() 视图函数里增加如下语句 不允许重复登录语句 if request.session.get('is_login',None): return HttpResponseRedirect(reverse('index')) 一旦用户名和密码输入正确,就往 session 字典内写入用户状态和数据 request.session['is_login'] = True request.session['user_id'] = db_us

  • Django中的session用法详解

    一.Session 的概念 cookie 是在浏览器端保存键值对数据,而 session 是在服务器端保存键值对数据 session 的使用依赖 cookie:在使用 Session 后,会在 Cookie 中存储一个 sessionid 的数据,每次请求时浏览器都会将这个数据发给服务器,服务器在接收到 sessionid 后,会根据这个值找出这个请求者的 Session. 二.Django 中 Session 的存储 session 键值对数据保存 session 的键值对数据默认保存在 dj

  • Django操作session 的方法

    session是存放在服务端的,在django中使用session必须要先在数据库中创建django_session表,session相关信息都要依赖此表 获取session request.session['status'] request.session.get('status')#一般用get,无此键返回None不报错 设置session #在使用session之前必须在数据库创建相关的表(django_session) #调用request.session首先会接收请求头部的cookie

  • django-利用session机制实现唯一登录的例子

    配置连接数据库 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': '数据库名称', 'USER': 'root', 'PASSWORD': '123456', 'HOST': '10.18.62.2', 'PORT': '3306', } } 生成session表 python manage.py makemigrations python manage.py migrate 登录时记住保存用户登录信

  • SpringBoot+SpringSession+Redis实现session共享及唯一登录示例

    最近在学习springboot,session这个点一直困扰了我好久,今天把这些天踩的坑分享出来吧,希望能帮助更多的人. 一.pom.xml配置 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency>

  • 利用JSP session对象保持住登录状态

    http协议本身是一种无状态的协议,也就是客户端连续发送的多个请求之间没有联系,下一次请求不关心上一次请求的状态. 而实际运用中却希望服务器能记住客户端请求的状态,比如在网上购物系统中,服务器端应该能够识别并跟踪每个登录到系统中的用户挑选并购买商品的整个流程 .为此,web服务器必须采用一种机制来唯一地标识一个用户,同时记录该用户的状态,这就要用到会话跟踪技术. Java Web使用Session来跟踪会话和管理会话内的状态. Session对象是一个jsp内置对象,它在第一个jsp页面被装载时

  • Django利用cookie保存用户登录信息的简单实现方法

    本文实例讲述了Django利用cookie保存用户登录信息的方法.分享给大家供大家参考,具体如下: 设置cookie response对象.set_cookie('key','value',多少秒后过期) 获取cookie request对象.COOKIES.get('key') 我们继续前一篇的代码 def hi(request): msg = {'result':''} loginSuccess = False # 是否登录成功标识 if user.userLogin(request.POS

  • Django利用Cookie实现反爬虫的例子

    我们知道,Diango 接收的 HTTP 请求信息里带有 Cookie 信息.Cookie的作用是为了识别当前用户的身份,通过以下例子来说明Cookie的作用.例: 浏览器向服务器(Diango)发送请求,服务器做出响应之后,二者便会断开连接(会话结束),下次用户再来请求服务器,服务器没有办法识别此用户是谁,比如用户登录功能,如果没有 Cookie 机制支持,那么只能通过查询数据库实现,并且每次刷新页面都要重新操作一次用户登录才可以识别用户,这会给开发人员带来大量的冗余工作,简单的用户登录功能会

  • Django中session进行权限管理的使用

    目录 1.urls.py 2.login/models.py 3.views.login和login.html 4.views.index 4.views.index 5.views.logout 6.总结session和forms的搭配 当session启用后,传递给视图request参数的HttpRequest对象将包含一个session属性,就像一个字典对象一样.你可以在Django的任何地方读写request.session属性,或者多次编辑使用它. 这个文件在我的C:\Users\17

  • Discuz!X中SESSION机制实例详解

    本文实例讲述了Discuz!X中SESSION机制.分享给大家供大家参考.具体如下: 在Discuz! X中一如继往的,SESSION 并没有使用 PHP 自带的 SESSION 机制,而是系统的一套自带的机制. 在数据库中可以看到有两个 SESSION 表: 一个是pre_common_adminsession,是管理员登录后台的 SESSION 表: 另一个是 pre_common_session 表,是所有用户在前台浏览页面时的 SESSION 表. 这两个表都是内存表(内存表的读写速度远

  • PHP根据session与cookie用户登录状态操作类的代码

     1.用户登录状态操作类UserLogin <?php final class UserLogin { public function __construct() { } public static function getUserInfo() { if (isset($_COOKIE["user_id"])&&$_COOKIE["user_id"]&&(trim($_COOKIE["user_id"])!=

  • SpringBoot集成redis与session实现分布式单点登录

    目录 单点登录 SSO(Single Sign On) 什么是单点登录? 实现方式 开发技术 单点登录实现流程 实现案例 看效果 前言: 由于考虑到cookie的安全性问题,就有了下面这个版本的sso 单点登录 SSO(Single Sign On) 什么是单点登录? 单点登录的英文名叫做:Single Sign On(简称SSO),指在同一帐号平台下的多个应用系统中,用户只需登录一次,即可访问所有相互信任的系统.简而言之,多个系统,统一登陆. 我们可以这样理解,在一个服务模块登录后,其他模块无

  • Django的session中对于用户验证的支持

    用户与Authentication 通过session,我们可以在多次浏览器请求中保持数据, 接下来的部分就是用session来处理用户登录了. 当然,不能仅凭用户的一面之词,我们就相信,所以我们需要认证. 当然了,Django 也提供了工具来处理这样的常见任务(就像其他常见任务一样). Django 用户认证系统处理用户帐号,组,权限以及基于cookie的用户会话. 这个系统一般被称为 auth/auth (认证与授权)系统. 这个系统的名称同时也表明了用户常见的两步处理. 我们需要 验证 (

随机推荐