(项目)在线教育平台(十二)

十七、首页和全局404、500页面配置

1、首页配置

  首页页面轮播课程需要在课程的model中添加is_banner字段,说明是否是轮播课程:

 1 class Course(models.Model):
 2     """课程"""
 3     DEGREE_CHOICES = (
 4         ('cj', '初级'),
 5         ('zj', '中级'),
 6         ('gj', '高级')
 7     )
 8 
 9     name = models.CharField('课程名', max_length=50)
10     desc = models.CharField('课程描述', max_length=300)
11     detail = models.TextField('课程详情')
12     degree = models.CharField('课程难度', choices=DEGREE_CHOICES, max_length=2)
13     learn_times = models.IntegerField('学习时长(分钟数)', default=0)
14     students = models.IntegerField('学习人数', default=0)
15     fav_nums = models.IntegerField('收藏人数', default=0)
16     click_nums = models.IntegerField('点击数', default=0)
17     image = models.ImageField('封面图', upload_to='courses/%Y/%m', max_length=100)
18     course_org = models.ForeignKey(CourseOrg, verbose_name='所属机构', on_delete=models.CASCADE, null=True, blank=True)
19     category = models.CharField('课程类别', max_length=20, default='')
20     tag = models.CharField('标签', max_length=10, default='')
21     teacher = models.ForeignKey(Teacher, verbose_name='机构讲师', on_delete=models.CASCADE, null=True, blank=True)
22     courseneed_know = models.CharField('课程须知', max_length=300, default='')
23     teacher_tellyou = models.CharField('老师告诉你', max_length=300, default='')
24     is_banner = models.BooleanField('是否轮播', default=False)
25     add_time = models.DateTimeField('添加时间', default=datetime.now)
26 
27     class Meta:
28         verbose_name = '课程'
29         verbose_name_plural = verbose_name
30 
31     # 获取章节数
32     def get_zj_nums(self):
33         return self.lesson_set.all().count()
34 
35     # 获取学习用户
36     def get_learn_users(self):
37         return self.usercourse_set.all()[:5]
38 
39     # 获取章节
40     def get_course_lesson(self):
41         return self.lesson_set.all()
42 
43     def __str__(self):
44         return self.name

  机构显示需要机构标签,在机构的model中添加tag字段:

 1 class CourseOrg(models.Model):
 2     """课程机构"""
 3     CATEGORY_CHOICES = (
 4         ('pxjg', '培训机构'),
 5         ('gx', '高校'),
 6         ('gr', '个人')
 7     )
 8     name = models.CharField('机构名称', max_length=50)
 9     category = models.CharField('机构类别', max_length=20, choices=CATEGORY_CHOICES, default='pxjg')
10     desc = models.TextField('机构描述')
11     students = models.IntegerField('学习人数', default=0)
12     course_nums = models.IntegerField('课程数', default=0)
13     click_nums = models.IntegerField('点击数', default=0)
14     fav_nums = models.IntegerField('收藏数', default=0)
15     image = models.ImageField('封面图', upload_to='org/%Y/%m', max_length=100)
16     address = models.CharField('地址', max_length=150)
17     city = models.ForeignKey(CityDict, verbose_name='所在城市', on_delete=models.CASCADE)
18     tag = models.CharField('机构标签', max_length=10, default='全国知名')
19     add_time = models.DateTimeField('添加时间', default=datetime.now)
20 
21     class Meta:
22         verbose_name = '课程机构'
23         verbose_name_plural = verbose_name
24 
25     # 获取教师数量
26     def get_teacher_nums(self):
27         return self.teacher_set.all().count()
28 
29     def __str__(self):
30         return self.name

  迁移数据库。

  首页的数据都是需要从后台获取的,先编写首页的接口:

 1 class IndexView(View):
 2     """首页"""
 3     def get(self, request):
 4         # 轮播图
 5         all_banners = Banner.objects.all().order_by('index')
 6 
 7         # 课程
 8         courses = Course.objects.filter(is_banner=False)[:6]
 9         # 轮播课程
10         banner_courses = Course.objects.filter(is_banner=True)[:3]
11 
12         # 机构
13         orgs = CourseOrg.objects.all()[:15]
14         return render(request, 'index.html', {
15             'all_banners': all_banners,
16             'courses': courses,
17             'banner_courses': banner_courses,
18             'orgs': orgs
19         })

  然后修改首页的url:

1 urlpatterns = [
2     path('', IndexView.as_view(), name='index'),  # 首页
3 ]

  修改前端首页页面中显示数据的代码:

  1 {% extends 'base.html' %}
  2 
  3 {% load staticfiles %}
  4 
  5 {% block title %}
  6     知能网 - 首页
  7 {% endblock %}
  8 
  9 {% block content %}
 10     <div class="banner">
 11             <div class="wp">
 12                 <div class="fl">
 13                     <div class="imgslide">
 14                         <ul class="imgs">
 15 {#                        遍历显示轮播图#}
 16                             {% for banner in all_banners %}
 17                                 <li>
 18                                     <a href="{{ banner.url }}">
 19                                         <img width="1200" height="478" src="{{ MEDIA_URL }}{{ banner.image }}" />
 20                                     </a>
 21                                 </li>
 22                             {% endfor %}
 23                         </ul>
 24                     </div>
 25                     <div class="unslider-arrow prev"></div>
 26                     <div class="unslider-arrow next"></div>
 27                 </div>
 28 
 29                 </div>
 30 
 31 
 32             </div>
 33 <!--banner end-->
 34 <!--feature start-->
 35     <section>
 36         <div class="wp">
 37             <ul class="feature">
 38                 <li class="feature1">
 39                     <img class="pic" src="/static/images/feature1.png"/>
 40                     <p class="center">专业权威</p>
 41                 </li>
 42                 <li class="feature2">
 43                     <img class="pic" src="/static/images/feature2.png"/>
 44                     <p class="center">课程最新</p>
 45                 </li>
 46                 <li class="feature3">
 47                     <img class="pic" src="/static/images/feature3.png"/>
 48                     <p class="center">名师授课</p>
 49                 </li>
 50                 <li class="feature4">
 51                     <img class="pic" src="/static/images/feature4.png"/>
 52                     <p class="center">数据真实</p>
 53                 </li>
 54             </ul>
 55         </div>
 56     </section>
 57 <!--feature end-->
 58 <!--module1 start-->
 59     <section>
 60         <div class="module">
 61             <div class="wp">
 62                 <h1>公开课程</h1>
 63                 <div class="module1 eachmod">
 64                     <div class="module1_1 left">
 65                         <img width="228" height="614" src="/static/images/module1_1.jpg"/>
 66                         <p class="fisrt_word">名师授课<br/>专业权威</p>
 67                         <a class="more" href="{% url 'course:course_list' %}">查看更多课程 ></a>
 68                     </div>
 69                     <div class="right group_list">
 70                         <div class="module1_2 box">
 71                             <div class="imgslide2">
 72                                 <ul class="imgs">
 73 {#                                遍历显示轮播课程#}
 74                                     {% for banner_course in banner_courses %}
 75                                         <li>
 76                                         <a href="{% url 'course:course_detail' banner_course.id %}">
 77                                             <img width="470" height="300" src="{{ MEDIA_URL }}{{ banner_course.image }}" />
 78                                         </a>
 79                                     </li>
 80                                     {% endfor %}
 81                                 </ul>
 82                             </div>
 83                             <div class="unslider-arrow2 prev"></div>
 84                             <div class="unslider-arrow2 next"></div>
 85                         </div>
 86 {#                        遍历显示课程#}
 87                             {% for course in courses %}
 88                                 <div class="module1_{{ forloop.counter|add:2 }} box">
 89                                 <a href="{% url 'course:course_detail' course.id %}">
 90                                     <img width="233" height="190" src="{{ MEDIA_URL }}{{ course.image }}"/>
 91                                 </a>
 92                                 <div class="des">
 93                                     <a href="{% url 'course:course_detail' course.id %}">
 94                                         <h2 title="{{ course.name }}">{{ course.name }}</h2>
 95                                     </a>
 96                                     <span class="fl">难度:<i class="key">{{ course.get_degree_display }}</i></span>
 97                                     <span class="fr">学习人数:{{ course.students }}</span>
 98                                 </div>
 99                                 <div class="bottom">
100                                     <span class="fl" title="慕课网">{{ course.course_org.name }}</span>
101                                     <span class="star fr">{{ course.fav_nums }}</span>
102                                 </div>
103                             </div>
104                             {% endfor %}
105                     </div>
106                 </div>
107             </div>
108         </div>
109     </section>
110     <section>
111         <div class="module greybg">
112             <div class="wp">
113                 <h1>课程机构</h1>
114                 <div class="module3 eachmod">
115                     <div class="module3_1 left">
116                         <img width="228" height="463" src="/static/images/module3_1.jpg"/>
117                         <p class="fisrt_word">名校来袭<br/>权威认证</p>
118                         <a class="more" href="{% url 'org:org_list' %}">查看更多机构 ></a>
119                     </div>
120                     <div class="right">
121                         <ul>
122 {#                        遍历显示机构#}
123                             {% for org in orgs %}
124                                 <li class="{% if forloop.counter|divisibleby:5 %}five{% endif %}">
125                                     <a href="{% url 'org:org_home' org.id %}">
126                                         <div class="company">
127                                             <img width="184" height="100" src="{{ MEDIA_URL }}{{ org.image }}"/>
128                                             <div class="score">
129                                                 <div class="circle">
130                                                     <h2>{{ org.tag }}</h2>
131                                                 </div>
132                                             </div>
133                                         </div>
134                                         <p><span class="key" title="{{ org.name }}">{{ org.name }}</span></p>
135                                     </a>
136                                 </li>
137                             {% endfor %}
138                         </ul>
139                     </div>
140                 </div>
141             </div>
142         </div>
143     </section>
144 {% endblock %}
145 
146 {% block custom_js %}
147     <script type="text/javascript" src="/static/js/index.js"></script>
148 {% endblock %}
index.html

  我们在登出然后登陆之后发现轮播图的数据不见了,需要修改登录接口中render首页的代码:

 1 class LoginView(View):
 2     """登录"""
 3     def get(self, request):
 4         return render(request, 'login.html')
 5 
 6     def post(self, request):
 7         # form实例化
 8         login_form = LoginForm(request.POST)
 9         if login_form.is_valid():
10             # form验证通过,获取用户提交的用户名和密码
11             user_name = request.POST.get('username', None)
12             pass_word = request.POST.get('password', None)
13 
14             # 通过django的authenticate方法获取user对象,也就是验证用户是否存在
15             user = authenticate(username=user_name, password=pass_word)
16 
17             if user is not None:
18                 if user.is_active:
19                     # 只有激活用户才能登录
20                     # 验证通过,通过django的login方法去登录,然后返回首页
21                     login(request, user)
22                     return HttpResponseRedirect(reverse('index'))
23                 else:
24                     # 验证不通过,返回登录页面,并将错误信息返回去显示
25                     return render(request, 'login.html', {'msg': '用户名或密码错误', 'login_form': login_form})
26             else:
27                 # 验证不通过,返回登录页面,并将错误信息返回去显示
28                 return render(request, 'login.html', {'msg': '用户名或密码错误', 'login_form': login_form})
29         else:
30             return render(request, 'login.html', {'login_form': login_form})

2、404、500页面配置

  404、500页面,必须在setting.py中设置DEBUG = False:

1 DEBUG = False
2 
3 ALLOWED_HOSTS = ['*']
4 
5 # 静态文件
6 STATIC_URL = '/static/'
7 STATIC_ROOT = os.path.join(BASE_DIR, 'static')

  在设置DEBUG = False后,django就不会代管你的静态文件,所以要在urls.py文件中设置url处理静态文件的url:

1 urlpatterns = [
2     re_path(r'^static/(?P<path>.*)', serve, {"document_root": STATIC_ROOT}),  # 静态文件显示
3 ]

  然后将404、500页面的html文件放到templates下即可配置完成。

十八、常见的web攻击与防护

1、sql注入攻击与防护

1.1 sql注入攻击的危害

  • 非法读取,篡改,删除数据库中的数据
  • 通过修改数据库来修改网页上的内容
  • 盗取用户的各类敏感信息
  • 注入木马等

1.2 SQL注入攻击原理

  比如下面一段代码:

 1 class LoginUnsafeView(View):
 2     def get(self, request):
 3         return render(request, "login.html", {})
 4     def post(self, request):
 5         user_name = request.POST.get("username", "")
 6         pass_word = request.POST.get("password", "")
 7 
 8         import MySQLdb
 9         conn = MySQLdb.connect(host='127.0.0.1', user='root', passwd='root', db='mxonline', charset='utf8')
10         cursor = conn.cursor()
11         sql_select = "select * from users_userprofile where email='{0}' and password='{1}'".format(user_name, pass_word)
12 
13         result = cursor.execute(sql_select)
14         for row in cursor.fetchall():
15             # 查询到用户
16             pass
17         print 'test'

  用户在登录的时候用户名如果输入 ' OR 1=1, 密码随便输入,SQL语句就变成了这样:

  select * from users_userprofile where email='' OR 1=1' and password='123',email='' or 1=1这条件就直接为True了,不用去执行后面的and语句了,那么是不是直接就将用户的信息拿到了呢,所以这种写法是非常危险的。

  那么如何去防护呢?可以尽量不去使用SQL原生语句去获取数据,可以通过django的orm去查询数据,在登录的使用使用django的login函数,这个函数是安全的。

2、xss攻击与防护

2.1 xss跨站脚本攻击的危害

  • 控制受害者机器向其他网站发起攻击,注入木马
  • 盗取各类用户账号
  • 非法转账等

2.2 xss攻击原理

  黑客将一段带有js代码的url发送给用户,用户点击这个url后发送请求到服务器,服务器返回数据给受害者,然后浏览器执行这段js脚本将用户的cookie信息发送给黑客,然后黑客拿着用户的cookie伪装成用户向服务器发送请求,这时黑客就可以进行任何攻击或者其他操作。

2.3 xss防护

  • 对用户输入的地方和变量都检查长度和对<>;'等字符做一些过滤
  • 不要在cookie中泄露用户的隐私数据,如用户名和密码
  • 将cookie和系统ip绑定来降低cookie泄露后的危险
  • 尽量采用POST方法而非GET提交表单

3、csrf攻击与防护

2.1 csrf攻击的危害

  • 以用户的名义去发送邮件
  • 盗取账号
  • 购买商品
  • 虚拟货币转账

2.2 csrf攻击的原理

  用户登录受信任的A服务器,服务器返回cookie,用户之后的每次请求都会带上cookie去访问A服务器,但是用户在同时的时候没有登出或者关闭A服务器的页面,直接去访问危险的B服务器,然后B服务器要求用户去访问A的一个url,这时信息就会泄露。

2.3 csrf攻击的防护

  在每个form中加上{{ csrf_token }}即可

posted @ 2018-11-23 13:52  Sweltering  阅读(578)  评论(0编辑  收藏  举报