目录

  1. 项目介绍和源码
  2. 拿来即用的bootstrap模板
  3. 服务器SSH服务配置与python中paramiko的使用
  4. 用户登陆与session;
  5. 最简单的实践之修改服务器时间
  6. 查看和修改服务器配置与数据库的路由
  7. 基于websocket的实时日志实现
  8. 查看服务器中的日志与前端的datatable的利用
  9. 重启服务器进程

前言

  这篇文章给出了网站的用户登陆模块,用户登录模块的网站后台实现主要通过Django权限系统auth来实现,相关逻辑可与参考这篇文章。作为一个网站新手,前后端交互基本上都是自己造轮子,利用javascript和ajax完成,登陆模块包括:用户登陆、用户注册、忘记密码,其中忘记密码是用简单的用户名+邮箱来验证的,时间充裕,可以进一步的通过发邮件链接跳转验证修改密码,图1简单描述了这个系统的结构。除此之外,这篇文章会涉及到第三方模态框sweetalert2的引用、给网页增加icon、对网页增加登陆验证、session保存登陆的用户名等小细节的完善。

功能实现

  前面文章已经提到,登陆网站时会优先进入登陆页面,进入app界面是由url控制的。先看下如何显示出登陆界面,这里依然秉承拿来即用的思想,把DASHGUM源文件夹的login.html文件改造下并将其重新命名为loginpage.html放在templates目录下,目录结构如下图2所示,其中login-bg.jpg为背景图,favicon.ico为网站的图标icon。

显示登陆页面

  • 修改DASHGUM源文件夹的login.html文件

  html代码中有两个模态框,一个管注册账号,一个管忘记密码,修改好的html重命名为loginpage.html放在上图的文件结构所示的位置。

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <title>登陆服务器</title>
  6. <!-- Bootstrap core CSS -->
  7. <link href="/templates/servermaterial/assets/css/bootstrap.css" rel="stylesheet">
  8. <!--external css-->
  9. <link href="/templates/servermaterial/assets/font-awesome/css/font-awesome.css" rel="stylesheet" />
  10. <!-- Custom styles for this template -->
  11. <link href="/templates/servermaterial/assets/css/style.css" rel="stylesheet">
  12. <link href="/templates/servermaterial/assets/css/style-responsive.css" rel="stylesheet">
  13. <!-- sweetalert2插件的css -->
  14. <link href="/templates/servermaterial/assets/SweetAlert2/dist/sweetalert2.css" rel="stylesheet">
  15. </head>
  16. <body>
  17. <section id="login-page">
  18. <header>
  19. <!--logo start-->
  20. <a class="logo" style="padding:10px 0 0 100px;"><h3><b>欢迎来到服务器工具</b></h3></a>
  21. </header>
  22. <div class="container" style="padding:200px 0 0 0">
  23. <form class="form-login">
  24. <h2 class="form-login-heading">登陆服务器</h2>
  25. <div class="login-wrap">
  26. <input type="text" name="username" id="loginusername" class="form-control" placeholder="账号" autofocus>
  27. <br>
  28. <input type="password" name="password" id="loginpassword" class="form-control" placeholder="密码">
  29. <label class="checkbox">
  30. <span class="pull-right">
  31. <a data-toggle="modal" href='#' onclick="show_forget_modal();">忘记密码</a>
  32. </span>
  33. </label>
  34. <button class="btn btn-theme btn-block" id='login' type="submit"><i class="fa fa-lock"></i> 登陆</button>
  35. <hr>
  36. <div class="registration">
  37. <a data-toggle="modal" href='#' onclick="show_create_modal();">注册账号</a>
  38. </div>
  39. </div>
  40. <!-- 忘记密码模态框 -->
  41. <div aria-hidden="true" aria-labelledby="myModalLabel" role="dialog" tabindex="-1" id="myModal_forget" class="modal fade">
  42. <div class="modal-dialog">
  43. <div class="modal-content">
  44. <div class="modal-header">
  45. <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
  46. <h4 class="modal-title">忘记密码 ?</h4>
  47. </div>
  48. <div class="modal-body">
  49. <p id="pforgetusername">请输入您的用户名:</p>
  50. <input type="text" name="forgetusername" placeholder="请输入需要找回的用户名" autocomplete="off" class="form-control placeholder-no-fix">
  51. <br>
  52. <p id="pforgetemail">请输入您的邮箱地址:</p>
  53. <input type="text" name="forgetemail" placeholder="请输入账号对应的Email" autocomplete="off" class="form-control placeholder-no-fix">
  54. <br>
  55. <p id='pnewpassword'>请设定您的新密码:</p>
  56. <input type="password" name="newpassword" placeholder="请输入新密码" autocomplete="off" class="form-control placeholder-no-fix">
  57. </div>
  58. <div class="modal-footer">
  59. <button data-dismiss="modal" class="btn btn-default" type="button">取消</button>
  60. <button class="btn btn-theme" id="forget" type="button">提交</button>
  61. </div>
  62. </div>
  63. </div>
  64. </div>
  65. <!-- 忘注册账号模态框 -->
  66. <div aria-hidden="true" aria-labelledby="myModalLabel" role="dialog" tabindex="-1" id="myModal_create" class="modal fade">
  67. <div class="modal-dialog">
  68. <div class="modal-content">
  69. <div class="modal-header">
  70. <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
  71. <h4 class="modal-title">注册账号</h4>
  72. </div>
  73. <div class="modal-body">
  74. <p id='pcreateusername'>请输入您的用户名:</p>
  75. <input type="text" name="createusername" placeholder="用户名(支持字母,数字,下划线)" autocomplete="off" class="form-control placeholder-no-fix">
  76. <br>
  77. <p id='pcreateemail'>请输入您的邮箱:</p>
  78. <input type="text" name="createemail" placeholder="请填写有效的邮箱地址" autocomplete="off" class="form-control placeholder-no-fix">
  79. <br>
  80. <p id='pcreatepassword'>请设定您的密码:</p>
  81. <input type="password" name="createpassword" placeholder="密码" autocomplete="off" class="form-control placeholder-no-fix">
  82. </div>
  83. <div class="modal-footer">
  84. <button data-dismiss="modal" class="btn btn-default" type="button">取消</button>
  85. <button class="btn btn-theme" id="create" type="button">注册</button>
  86. </div>
  87. </div>
  88. </div>
  89. </div>
  90. <!-- modal -->
  91. </form>
  92. </div>
  93. </section>
  94. <!-- js placed at the end of the document so the pages load faster -->
  95. <script src="/templates/servermaterial/assets/js/jquery.js"></script>
  96. <script src="/templates/servermaterial/assets/js/bootstrap.min.js"></script>
  97. <!-- sweetalert2插件的js -->
  98. <script src="/templates/servermaterial/assets/SweetAlert2/dist/sweetalert2.js"></script>
  99. <!--BACKSTRETCH-->
  100. <!-- You can use an image of whatever size. This script will stretch to fit in any screen size.-->
  101. <script type="text/javascript" src="/templates/servermaterial/assets/js/jquery.backstretch.min.js"></script>
  102. <script>
  103. // 在这里设置背景图
  104. $.backstretch("/templates/login-bg.jpg", {speed: 500});
  105. </script>
  106. </body>
  107. </html>
  • 为页面添加urls和views

  在WebTool的urls.py中加入url如下:

  1. from django.conf.urls import include, url
  2. from django.contrib import admin
  3. import views
  4. urlpatterns = [
  5. url(r'^admin', admin.site.urls),
  6. # 用127.0.0.1:8888访问网址时会默认转到loginpage
  7. url(r'^$', views.loginpage),
  8. # 用127.0.0.1:8888/loginpage访问网址时会转到loginpage
  9. url(r'^loginpage/', views.loginpage),
  10. ]

  在WebTool的views.py添加代码:

  1. from __future__ import unicode_literals
  2. from django.shortcuts import render_to_response
  3. from django.http import JsonResponse
  4. # 登陆页面
  5. def loginpage(request):
  6. return render_to_response("loginpage.html")

  构建项目之后,访问127.0.0.1:8888或者127.0.0.1:8888/loginpage将会显示出登陆界面,如图3。

  • 修改网站的icon

  默认情况下,网站是没有icon的,我们要向网站添加一个如图4中红框的icon。可以先把icon资源放在图2目录结构中(favicon.ico),然后再在WebTool的urls.py中加入url如下:

  1. from django.conf.urls import include, url
  2. from django.contrib import admin
  3. from django.views.generic.base import RedirectView
  4. import views
  5. urlpatterns = [
  6. url(r'^admin', admin.site.urls),
  7. url(r'^$', views.loginpage),
  8. url(r'^loginpage/', views.loginpage),
  9. # 为网站添加icon
  10. url(r'^favicon.ico$', RedirectView.as_view(url='/templates/favicon.ico')),
  11. ]

用户注册

  用户注册的html代码已经在前面一并给出了,其实就是一个模态框,如图5,现在我们只需要编写控制它的javascript代码就好。但是在写的时候需要考虑到一些情况,比如用户名、邮箱、密码未填写、不合法、用户名已经注册过了这些情况,用户名、邮箱、密码未填写、不合法可以直接在前端自己写逻辑判断(我这里都是自己造轮子,一些框架已经集成这些功能,并不需要写一堆javascript代码)。然后弹出来的提示框用了sweetalert2插件,这里会说一下该插件的引用。

  • 配合上面给出的html的javascript代码
  1. <script>
  2. // 显示注册账号的模态框
  3. function show_create_modal(){
  4. $("input[name='createusername']").val("");
  5. $("input[name='createpassword']").val("");
  6. $("input[name='createemail']").val("");
  7. document.getElementById("pcreateusername").style.color = 'black';
  8. document.getElementById("pcreatepassword").style.color = 'black';
  9. document.getElementById("pcreateemail").style.color = 'black';
  10. $('#myModal_create').modal('show');
  11. }
  12. </script>
  13. <script>
  14. // 注册按钮
  15. $("#create").click(function(){
  16. var user = $("input[name='createusername']").val();
  17. var code = $("input[name='createpassword']").val();
  18. var email = $("input[name='createemail']").val();
  19. // 账号未填写
  20. if (user==''){
  21. document.getElementById("pcreateusername").style.color = 'red';
  22. $("input[name='createusername']").focus();
  23. return ;
  24. }
  25. // 账号名合法
  26. var uPattern = /^[a-zA-Z0-9_]{4,16}$/;
  27. if (!uPattern.test(user)){
  28. document.getElementById("pcreateusername").innerHTML = '请输入合法的用户名';
  29. document.getElementById("pcreateusername").style.color = 'red';
  30. $("input[name='createusername']").val("").focus();
  31. return ;
  32. }
  33. // 邮箱未填写
  34. if (email==''){
  35. document.getElementById("pcreateemail").style.color = 'red';
  36. $("input[name='createemail']").focus();
  37. return ;
  38. }
  39. // 邮箱合法
  40. var ePattern = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
  41. if (!ePattern.test(email)){
  42. document.getElementById("pcreateemail").innerHTML = '请输入合法的邮箱';
  43. document.getElementById("pcreateemail").style.color = 'red';
  44. $("input[name='createemail']").val("").focus();
  45. return ;
  46. }
  47. // 密码未填写
  48. if (code==''){
  49. document.getElementById("pcreatepassword").style.color = 'red';
  50. $("input[name='createpassword']").focus();
  51. return ;
  52. }
  53. // ajax请求注册
  54. $.ajax({
  55. url:"/createuser",
  56. type:'POST',
  57. data:{'user': user, 'email': email,'code': code},
  58. success: function(arg){
  59. ret = eval(arg);
  60. if(ret.status){
  61. swal({
  62. type: 'success',
  63. title: '注册成功!',
  64. confirmButtonText: '确定',
  65. confirmButtonColor: '#4cd964'
  66. }).then(function(){
  67. // 注册成功后刷新页面
  68. window.location.reload();
  69. });
  70. }else{
  71. swal({
  72. type: 'error',
  73. title: '用户名已存在!',
  74. confirmButtonText: '确定',
  75. confirmButtonColor: '#4cd964'
  76. })
  77. }
  78. }
  79. });
  80. })
  81. </script>

  上面中的ajax请求到后台的url即createuser。后台的urls和views代码响应前端的请求。

  • 注册账号的urls和views

  WebTool中urls.py如下,增加一个处理createuser:

  1. from django.conf.urls import include, url
  2. from django.contrib import admin
  3. from django.views.generic.base import RedirectView
  4. import views
  5. urlpatterns = [
  6. url(r'^admin', admin.site.urls),
  7. url(r'^$', views.loginpage),
  8. url(r'^favicon.ico$', RedirectView.as_view(url='/templates/favicon.ico')),
  9. url(r'^loginpage/', views.loginpage),
  10. # 处理前端的ajax请求createuser
  11. url(r'^createuser', views.createuser),
  12. ]

  WebTool中views.py如下:

  1. # -*- coding: utf-8 -*-
  2. from __future__ import unicode_literals
  3. from django.shortcuts import render_to_response
  4. from django.http import JsonResponse
  5. from django.contrib.auth.models import User
  6. from django.contrib.auth import login, authenticate
  7. # 创建账户
  8. def createuser(request):
  9. ret = {'status': False, 'reason': ''}
  10. if request.method == 'POST':
  11. username = request.POST.get('user')
  12. email = request.POST.get('email')
  13. password = request.POST.get('code')
  14. try:
  15. # 创建用户
  16. user = User.objects.create_user(username, email, password)
  17. user.save()
  18. except Exception as e:
  19. # 用户名已经在数据库存在
  20. if e[0] == 1062:
  21. ret['reason'] = 'repeated'
  22. ret['status'] = False
  23. return JsonResponse(ret)
  24. ret['status'] = True
  25. return JsonResponse(ret)
  • sweetalert2的引入

  sweetalert2是一类提示模态框,可以在这个链接中体验,我们把插件应用在项目里取代原生的生硬警示框。首先,把这个资源下载下来放到本地的资源文件夹里。注意到,在上面的html文件中已经插入了两行关于这个插件的css和js地址:

  1. <link href="/templates/servermaterial/assets/SweetAlert2/dist/sweetalert2.css" rel="stylesheet">
  2. <script src="/templates/servermaterial/assets/SweetAlert2/dist/sweetalert2.js"></script>

  引入上面两个文件后,通过js代码中swal就可以使用这个警示框了,当我们利用ajax请求到后台注册成功时,前端就会弹出这个警示框告诉使用者已经注册成功了,然后刷新页面,下面的代码来自于上面注册用户的javascript代码中。注册成功的效果如图7,后面的警示框都会使用这个样式。

  1. swal({
  2. type: 'success',
  3. title: '注册成功!',
  4. confirmButtonText: '确定',
  5. confirmButtonColor: '#4cd964'
  6. }).then(function(){
  7. window.location.reload();
  8. });

用户登陆与session

  • 用户登陆的javascript代码与session
  1. $('form').submit(function(event){
  2. event.preventDefault();
  3. var username = $("input[name='username']").val();
  4. var password = $("input[name='password']").val();
  5. // 用户名未填写
  6. if (username==''){
  7. document.getElementById("loginusername").setAttribute("placeholder","请填写用户名");
  8. $("input[name='username']").focus();
  9. return ;
  10. }
  11. // 用户名合法
  12. var uPattern = /^[a-zA-Z0-9_]{4,16}$/;
  13. if (!uPattern.test(username)){
  14. document.getElementById("loginusername").setAttribute("placeholder","请输入合法的用户名");
  15. $("input[name='username']").val("").focus();
  16. return ;
  17. }
  18. // 密码未填写
  19. if (password==''){
  20. document.getElementById("loginpassword").setAttribute("placeholder","请输入密码");
  21. $("input[name='password']").focus();
  22. return ;
  23. }
  24. // 请求登陆
  25. $.ajax({
  26. url:"/userlogin",
  27. type:'POST',
  28. data:{'username': username, 'password': password},
  29. success: function(arg){
  30. ret = eval(arg);
  31. if(ret.status){
  32. window.location.href='/server';
  33. }else{
  34. swal({
  35. type: 'error',
  36. title: '密码错误,请重新登陆!',
  37. confirmButtonText: '确定',
  38. confirmButtonColor: '#4cd964'
  39. })
  40. }
  41. }
  42. });
  43. })

  上面中的ajax请求到后台的url即userlogin。后台的urls和views代码响应前端的请求。

  • 用户登陆的urls和views

  WebTool中urls.py如下,增加一个处理createuser和url(r'^server/', include('server.urls', namespace="server"))前者的目的是接受ajax的登录请求,后者的作用是当ajax返回可以登陆的时候,利用它进入到server这个app里面,即127.0.0.1/server,进入127.0.0.1/server之后的路由和响应由server中的urls和views控制,如当你请求127.0.0.1/server/home时。

  1. from django.conf.urls import include, url
  2. from django.contrib import admin
  3. from django.views.generic.base import RedirectView
  4. import views
  5. urlpatterns = [
  6. url(r'^admin', admin.site.urls),
  7. url(r'^$', views.loginpage),
  8. url(r'^favicon.ico$', RedirectView.as_view(url='/templates/favicon.ico')),
  9. url(r'^loginpage/', views.loginpage),
  10. url(r'^createuser', views.createuser),
  11. # 用户登陆
  12. url(r'^userlogin', views.userlogin),
  13. # 登陆成功后进入127.0.0.1:8888/server页面
  14. url(r'^server/', include('server.urls', namespace="server")),
  15. ]

  WebTool中views.py如下,在这里使用到了session,方便在进入app页面之后依然能够让网站从session中提取到现在登陆的用户名,django中的session用起来很简单,因为它实际上是使用一个字典实现的,需要记录的时候调用request.session['XX'] = XXX。需要使用的时候可以调用request.session.get('XX'),我们在这里利用session保存了用户名,目的就是在后面的网页中可以随时取出来。
  在使用session之前,需要在django的配置文件settings.py中添加与session相关的配置如下:

  1. # session配置
  2. SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
  3. SESSION_EXPIRE_AT_BROWSER_CLOSE = True

  SESSION_ENGINE是存储session的方式,常用的有两种,分别是django.contrib.sessions.backends.cache和django.contrib.sessions.backends.db,前者存储在缓存中,可能面临丢失和溢出的风险,后者存储在数据库中,有性能开销但是安全。
  SESSION_EXPIRE_AT_BROWSER_CLOSE设置为True代表关闭浏览器就会清除session。

  1. # -*- coding: utf-8 -*-
  2. from __future__ import unicode_literals
  3. from django.shortcuts import render_to_response
  4. from django.http import JsonResponse
  5. from django.contrib.auth.models import User
  6. from django.contrib.auth import login, authenticate
  7. # 用户登陆
  8. def userlogin(request):
  9. ret = {'status': False, 'reason': ''}
  10. if request.method == 'POST':
  11. username = request.POST.get('username')
  12. password = request.POST.get('password')
  13. user = authenticate(username=username, password=password)
  14. if user is not None:
  15. # 将用户名记录在session中,方便传递
  16. request.session['username'] = username
  17. if user.is_active:
  18. login(request, user)
  19. ret['status'] = True
  20. else:
  21. ret['reason'] = 'codewrong'
  22. return JsonResponse(ret)

忘记密码并通过邮箱重置

  这个逻辑和用户注册逻辑很相似,唯独不一样的是,如果用户忘记了密码,可以通过邮箱找回来(这里为了方便,没有实现利用邮件中的链接重置密码),后台仅仅是核对邮箱和用户名匹配后就允许用户设置新密码,时间充裕可以实现完整的逻辑。忘记密码的模态框如图8所示。

  • 用户忘记密码的javascript代码
  1. <script>
  2. function show_forget_modal(){
  3. $("input[name='forgetusername']").val("");
  4. $("input[name='forgetemail']").val("");
  5. $("input[name='newpassword']").val("");
  6. document.getElementById("pforgetusername").style.color = 'black';
  7. document.getElementById("pforgetemail").style.color = 'black';
  8. document.getElementById("pnewpassword").style.color = 'black';
  9. $('#myModal_forget').modal('show');
  10. }
  11. </script>
  12. <script>
  13. $("#forget").click(function(){
  14. var username = $("input[name='forgetusername']").val();
  15. var email = $("input[name='forgetemail']").val();
  16. var newpassword = $("input[name='newpassword']").val();
  17. // 账号未填写
  18. if (username==''){
  19. document.getElementById("pforgetusername").style.color = 'red';
  20. $("input[name='forgetusername']").focus();
  21. return ;
  22. }
  23. // 账号名合法
  24. var uPattern = /^[a-zA-Z0-9_]{4,16}$/;
  25. if (!uPattern.test(username)){
  26. document.getElementById("pforgetusername").innerHTML = '请输入合法的用户名';
  27. document.getElementById("pforgetusername").style.color = 'red';
  28. $("input[name='forgetusername']").val("").focus();
  29. return ;
  30. }
  31. // 邮箱未填写
  32. if (email==''){
  33. document.getElementById("forgetemail").style.color = 'red';
  34. $("input[name='pforgetemail']").focus();
  35. return ;
  36. }
  37. // 邮箱合法
  38. var ePattern = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
  39. if (!ePattern.test(email)){
  40. document.getElementById("pforgetemail").innerHTML = '请输入合法的邮箱';
  41. document.getElementById("pforgetemail").style.color = 'red';
  42. $("input[name='forgetemail']").val("").focus();
  43. return ;
  44. }
  45. // 密码未填写
  46. if (newpassword==''){
  47. document.getElementById("pnewpassword").style.color = 'red';
  48. $("input[name='newpassword']").focus();
  49. return ;
  50. }
  51. $.ajax({
  52. url:"/forgetusr",
  53. type:'POST',
  54. data:{'username': username, 'email': email, 'newpassword': newpassword},
  55. success: function(arg){
  56. ret = eval(arg);
  57. if(ret.status){
  58. swal({
  59. type: 'success',
  60. title: '密码修改成功!',
  61. confirmButtonText: '确定',
  62. confirmButtonColor: '#4cd964'
  63. }).then(function(){
  64. window.location.reload();
  65. });
  66. }else{
  67. // 账号不存在
  68. if(ret.reason == 'unexist'){
  69. swal({
  70. type: 'error',
  71. title: '账号不存在,请重试!',
  72. confirmButtonText: '确定',
  73. confirmButtonColor: '#4cd964'
  74. })
  75. }
  76. // 邮箱错误
  77. if(ret.reason == 'emailwrong'){
  78. swal({
  79. type: 'error',
  80. title: '账号对应邮箱不正确,请重试!',
  81. confirmButtonText: '确定',
  82. confirmButtonColor: '#4cd964'
  83. })
  84. }
  85. }
  86. }
  87. });
  88. })
  89. </script>

  上面中的ajax请求到后台的url即forgetusr。后台的urls和views代码响应前端的请求。

  • 忘记密码的urls和views

  WebTool中urls.py如下,增加一个处理forgetusr的url:

  1. from django.conf.urls import include, url
  2. from django.contrib import admin
  3. from django.views.generic.base import RedirectView
  4. import views
  5. urlpatterns = [
  6. url(r'^admin', admin.site.urls),
  7. url(r'^$', views.loginpage),
  8. url(r'^favicon.ico$', RedirectView.as_view(url='/templates/favicon.ico')),
  9. url(r'^loginpage/', views.loginpage),
  10. url(r'^createuser', views.createuser),
  11. url(r'^userlogin', views.userlogin),
  12. # 处理ajax发起的忘记密码逻辑
  13. url(r'^forgetusr', views.forgetusr),
  14. url(r'^server/', include('server.urls', namespace="server")),
  15. ]

  WebTool中views.py如下,增加一个处理forgetusr相应的请求:

  1. # -*- coding: utf-8 -*-
  2. from __future__ import unicode_literals
  3. from django.shortcuts import render_to_response
  4. from django.http import JsonResponse
  5. from django.contrib.auth.models import User
  6. from django.contrib.auth import login, authenticate
  7. # 忘记密码
  8. def forgetusr(request):
  9. ret = {'status': False, 'reason': ''}
  10. if request.method == 'POST':
  11. username = request.POST.get('username')
  12. email = request.POST.get('email')
  13. newpassword = request.POST.get('newpassword')
  14. try:
  15. user = User.objects.get(username=username)
  16. except User.DoesNotExist:
  17. # 账号不存在
  18. ret['reason'] = 'unexist'
  19. return JsonResponse(ret)
  20. email_ = User.objects.get(username=user).email
  21. # 用户名对应邮箱错误
  22. if email_ != email:
  23. ret['reason'] = 'emailwrong'
  24. return JsonResponse(ret)
  25. user.set_password(newpassword)
  26. user.save()
  27. ret['status'] = True
  28. return JsonResponse(ret)

app中增加登出逻辑和用户名

  app即server,用户登录后就会进入这个app页面,即服务器工具。

  • app中显示登陆人的用户名

  文章拿来即用的bootstrap模板显示出的网站页面中左上角的用户名其实是已经写好的,如图9,现在我们可以利用sessions来换成实际的登陆人的用户名。只需要把server/views.py中的homepage函数重新写下就好,然后重新走一遍登陆流程,就可以得到图10,显示为实际登陆人的用户名。

  1. # -*- coding: utf-8 -*-
  2. from __future__ import unicode_literals
  3. from django.shortcuts import render_to_response
  4. from django.contrib.auth import logout
  5. from django.http import JsonResponse
  6. from django.contrib.auth.decorators import login_required
  7. # 服务器的名字
  8. htmltitle = '服务器工具'
  9. def homepage(request):
  10. username = request.session.get('username')
  11. pagedict = {'title': htmltitle, 'username': username}
  12. return render_to_response('servermaterial/home.html', pagedict)

  • app中增加用户登出

  还记得在前面的文章拿来即用的bootstrap模板显示出的网站页面中,在右上角有一个退出服务器的按钮用来登出用户,如图11,我们这里对这个按钮完善一下。同样注意的是,这里修改的应该是app即server中的文件(urls.py、views.py),资源文件base.html也是对应的。
  在base.html中添加一个对这个按钮的控制代码:

  1. $(".logout").click(function(){
  2. $.ajax({
  3. url:"userlogout",
  4. type:'GET',
  5. success: function(arg){
  6. ret = eval(arg);
  7. if(ret.status){
  8. window.location.href = '/loginpage'
  9. }
  10. }
  11. })
  12. });

  在server中的urls.py中添加一个url:url(r'^userlogout', views.userlogout)
  在server中的urls.py中添加一个后台响应:

  1. # -*- coding: utf-8 -*-
  2. from __future__ import unicode_literals
  3. from django.shortcuts import render_to_response
  4. from django.contrib.auth import logout
  5. from django.http import JsonResponse
  6. from django.contrib.auth.decorators import login_required
  7. # 用户登出
  8. def userlogout(request):
  9. ret = {'status': True}
  10. if request.method == 'GET':
  11. # 用户登出
  12. logout(request)
  13. return JsonResponse(ret)

为页面增加权限鉴定

  虽然添加了用户登陆,但是我们依然可以通过输入完整的url来越过登陆,例如我们可以通过127.0.0.1:8888/server/home直接进入服务器工具的主页,而越过了127.0.0.1:8888/loginpage的登陆,这明显是不被允许的。为了防止这样做,我们可以将所有的可以通过直接输入url浏览到的页面的view函数加一个装饰器。例如:对127.0.0.1:8888/server/home对应的页面渲染函数homepage增加一个装饰器,加了装饰器之后用户就没有办法直接跳过登陆进入服务器工具页面。装饰器是python的一种特性,如果进一步了解可以看下这篇文章

  1. # -*- coding: utf-8 -*-
  2. from __future__ import unicode_literals
  3. from django.shortcuts import render_to_response
  4. from django.contrib.auth import logout
  5. from django.http import JsonResponse
  6. from django.contrib.auth.decorators import login_required
  7. # 服务器的名字
  8. htmltitle = '服务器工具'
  9. @login_required(login_url='/loginpage')
  10. def homepage(request):
  11. username = request.session.get('username')
  12. pagedict = {'title': htmltitle, 'username': username}
  13. return render_to_response('servermaterial/home.html', pagedict)

结语

  本篇文章主要介绍了用户系统的实现,作为一个小白,里面的html和javascript都是手写,基本上基于ajax实现,但是其实这样并不效率,成熟的web网站会将前后端分开,使得开发人员更专注于后端或者前端的开发。

django搭建一个小型的服务器运维网站-用户登陆与session的更多相关文章

  1. django搭建一个小型的服务器运维网站-拿来即用的bootstrap模板

    目录 项目介绍和源码: 拿来即用的bootstrap模板: 服务器SSH服务配置与python中paramiko的使用: 用户登陆与session; 最简单的实践之修改服务器时间: 查看和修改服务器配 ...

  2. django搭建一个小型的服务器运维网站-查看和修改服务器配置与数据库的路由

    目录 项目介绍和源码: 拿来即用的bootstrap模板: 服务器SSH服务配置与python中paramiko的使用: 用户登陆与session; 最简单的实践之修改服务器时间: 查看和修改服务器配 ...

  3. django搭建一个小型的服务器运维网站-查看服务器中的日志与前端的datatable的利用

    目录 项目介绍和源码: 拿来即用的bootstrap模板: 服务器SSH服务配置与python中paramiko的使用: 用户登陆与session; 最简单的实践之修改服务器时间: 查看和修改服务器配 ...

  4. django搭建一个小型的服务器运维网站-重启服务器的进程

    目录 项目介绍和源码: 拿来即用的bootstrap模板: 服务器SSH服务配置与python中paramiko的使用: 用户登陆与session; 最简单的实践之修改服务器时间: 查看和修改服务器配 ...

  5. django搭建一个小型的服务器运维网站

    前言   不管是运维还是开发抑或是测试,工作中不免会和Linux服务器打交道,常见的操作譬如:查看CPU或内存状态.查看和修改服务器时间.查看或者修改服务器配置文件.实时查看或回看系统的日志.重启服务 ...

  6. 10分钟搭建一个小型网页(python django)(hello world!)

    10分钟搭建一个小型网页(python django)(hello world!) 1.安装django pip install django 安装成功后,在Scripts目录下存在django-ad ...

  7. 初学django搭建一个通讯录应用

    ---恢复内容开始--- django搭建一个通讯录应用 一.环境介绍 window10 64位 Django-1.5.12 python 2.7 Sqlite3 二.基本安装 python2.7安装 ...

  8. 搭建一个webpack微服务器

    [前言]:因为最近在vue2.0的时候用到了webpack的externals,才发现我之前都只是用webpack做一些搭建完项目后的“收尾工作”——即打包,而没有把它纳入到项目开发的“主体过程”中来 ...

  9. 【日记】搭建一个node本地服务器

    用node搭建一个本地http服务器.首先了解htpp服务器原理 HTTP协议定义Web客户端如何从Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端.HTTP协议采用了请求/响应模型 ...

随机推荐

  1. vue组件父与子通信-登录窗口

    一.组件间通信(父组件    -->  子组件)步骤:①父组件在调用子组件 传值 <child-component myValue="123"> </chi ...

  2. 【ABAP系列】SAP ABAP 优化LOOP循环的一点点建议

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP 优化LOOP循 ...

  3. 手把手教你用Pytorch-Transformers——部分源码解读及相关说明(一)

    一.简介 Transformers是一个用于自然语言处理(NLP)的Python第三方库,实现Bert.GPT-2和XLNET等比较新的模型,支持TensorFlow和PyTorch.本文介对这个库进 ...

  4. Java类和对象的内存分配

    类的加载时机: 1.创建对象 2.调用类的静态成员 3.加载子类 类在实例化后的内存分配 1.每次创建对象时,都需要进行加载和创建2个操作: ① 先去判断需要的类是否已经加载,如果已经加载了,则无需再 ...

  5. <每日一题> Day7:CodeForces-1166C.A Tale of Two Lands (二分 + 排序)

    原题链接 参考代码: #include <cstdio> #define mid ((l + r) / 2) #include <algorithm> using namesp ...

  6. 在学习linux磁盘管理期间学习的逻辑卷管理笔记

    LVM(逻辑分区)的创建顺序:物理分区-物理卷-卷组-逻辑卷-挂载. 物理卷(Physical Volume,PV):就是指硬盘分区,也可以是整个硬盘或已创建的软RAID,是LVM的基本存储设备. 卷 ...

  7. Python中包的定义

    简单来说,包就是文件夹,但该文件夹下必须存在 __init__.py 文件, 该文件的内容可以为空.__init__.py 用于标识当前文件夹是一个包. 实例子 test.pypackage_dc36 ...

  8. C# ASP.NET 手写板并生成图片保存

    前端: @{ Layout = null; } <!DOCTYPE html> <html lang="zh-CN"> <head> <t ...

  9. WinForm的RadioButton使用小技巧

    http://www.cnblogs.com/sjrhero/articles/1883155.html 当多个RadioButton同在一个容器里面的时候,多半的操作都是要得到其中一个的值这个时候我 ...

  10. Vue-cli2项目文件目录解析

    前言 不是原创,真的不是原创,主要我是根据CSDN的一篇文章和其他平台上的文章整理而来,在最后我会贴上所有原文的地址,下面正式进入正文. Vue-cli项目文件目录结构 这个是Vue-cli2.0版本 ...