欢迎食用『主界面』~,这里是赵苦瓜的看板娘desu~

#
【点滴记录】Django框架的入门 - 第五篇(会话技术、CSRF)
首页 > 点滴记录    作者:赵苦瓜   2021年1月29日 14:26 星期五   热度:6228°   百度已收录  
时间:2021-1-29 14:26   热度:6228° 

上一篇主要讲了HttpResponse,URL反向解析等,戳链接:https://blog.jixiaob.cn/?post=41

————————————————————————————————————————————


爬虫

————————————————————————————————————————————

模拟人去请求数据

提取数据

存储数据

核心内容:数据爬取、数据提取、数据存储、提上效率(进程、线程、协程)


会话技术

————————————————————————————————————————————

出现场景:服务器如何识别客户端

Http在Web开发中基本都是短连接

请求生命周期:从Request开始,到Response结束

种类:

Cookie:客户端会话技术,数据存储在客户端,以键值对存储,支持过期时间,默认Cookie会自动携带,本网站所有Cookie,跨域名,跨网站,通过HttpResponse操作客户端

Session:服务端会话技术,数据存储在服务器中,默认存储在内存中。Django中默认会把Session持久化到数据库中。

Token:服务端会话技术,可以理解为自定义的Session


Cookie

——————————————————————————————————————————

设置和获取Cookie

def set_cookie(request):
    response = HttpResponse('设置Cookie')
    response.set_cookie('username', 'Rock')
    return response


def get_cookie(request):
    username = request.COOKIES.get('username')
    return HttpResponse(username)
(我发现有些管理浏览器Cookie的插件是可以任意修改Cookie的)


Cookie不能跨浏览器,不能跨域名

Cookie默认不支持中文==>可以进行转换  Base64

response.set_cookie(key,value,max_age=None,exprise=None)   

不设置的话默认关闭浏览器即失效

max_age 整数,指定Cookie过期时间  (秒)

exprise 整数,指定过期时间,还支持一是一个datetime或timedelta(时间差),可以指定一个具体日期时间

(这俩指定一个就可以了)


上面的都是明文的Cookie,比较不安全

还可以对Cookie进行加盐(加密)


response.set_signed_cookie('uname', uname, 'Rock')       后面的'Rock'就是salt     这个uname必须存在,不存在会引发异常,可采用Try异常处理解决。

def mine(request):
    # uname = request.COOKIES.get('uname')
    try:
        uname = request.get_signed_cookie('uname', salt='Rock')
        if uname:
            # return HttpResponse(uname)
            return render(request, 'mine.html', context={'uname': uname})
    except Exception as e:
        print('获取失败')
    return redirect('login')



获取的时候需要解密

uname = request.get_signed_cookie('uname', salt='Rock')

salt必须一样,要不然不认


登录

————————————————————————————————————————

Cookie登录

首先有一个页面,页面中有输入框和登录按钮,点完登录默认进入个人中心

个人中心可以显示用户名

简易登录页面(没有密码)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
<form action="{% url 'do_login' %}" method="post">
    <span>用户名:</span><input type="text" placeholder="请输入用户名" name="uname">
    <br>
    <button>登录</button>
    
    
</form>
</body>
</html>
def login(request):
    return render(request, 'login.html')


def do_login(request):
    uname = request.POST.get('uname')
    response = HttpResponseRedirect(reverse('mine'))
    response.set_cookie('uname', uname, max_age=60)
    return response


def mine(request):
    uname = request.COOKIES.get('uname')
    if uname:
        return HttpResponseRedirect(uname)   # 没登录,重定向到登录页面
    return redirect('login')



然后注销登录

def logout(request):
    response = redirect(reverse('login'))
    response.delete_cookie('uname')
    return response


优秀程序:松耦合(解耦合),高内聚

比如登录页面和接受登录请求的页面坐到一起



Session登录

————————————————————————————————————————

Django中Session默认过期时间为14天

主键是字符串

数据是使用数据安全的(Base64)

支持中文

解码之后是这样的:

35a348988037089681f8f23960164fa599c5f310:{"username":"\u53cc\u51fb6666"}
前面的是混淆串  后面就是输入的用户名 双击6663


Session依赖于Cookie   sessionid     session_key

def login(request):
    if request.method == 'GET':
        return render(request, 'login.html')
    elif request.method == 'POST':
        username = request.POST.get('username')
        request.session['username'] = username   # 存数据的方法
        return HttpResponse("登录成功")
def mine(request):
    username = request.session.get('username')   # 用key访问也可以,但是不存在会抛异常
    return HttpResponse(username)


注意:使用Cookie注销登录直接删Cookie就行了,但是使用Session登录时一定不能直接删Cookie,会产生垃圾数据影响服务器性能。

删session:  del request.session('username')     # 这个只是会删除内容,不会删除那一条session数据

delete request['sessionid']  删除会话

clear()删除当前会话的数据

最好的删除方法:request.session.flush()     #    当前会话的 session cookie 一起干掉


Token

————————————————————————————————————————

先在模型中定义一个s_token = models.CharField(max_length=256)

生成Token,可以采用ip+time+用户名的方式然后再进行md5加密算法的操作

ip = request.META.get('REMOTE_ADDR')

生成好Token之后存到数据库中(登录成功之后)

s_token = token

然后设定一个cookie

response.set_cookie('token', token)

之后确认登录状态时就获取cookie的token信息,再到数据库里面找

如果是移动端的话,返回的都是Json,获取token采用get方式获取,移动端储存自己的Token,获取时主动传递。


Cookie,Session,Token对比:

————————————————————————————————————————

Cookie使用更简洁,对服务器压力小,但是数据不安全

Session服务器要维护,相对安全。

Token拥有Session的所有优点,自己维护略麻烦,支持更多的终端


CSRF
——————————————————————————————————————————

默认直接POST会直接403,所以之前我们注释了一条csrf

'django.middleware.csrf.CsrfViewMiddleware',

如何授权呢?

在HTML的form里面加上{% csrf_token %}即可

放跨站攻击,防止恶意注册(请求),确保客户端是我们自己的客户端。

使用了cookie中的csrftoken进行验证,传输

服务器发送给客户端,客户端将cookie获取过来,还要进行编码转换(数据安全)

如何实现的?在我们存在的csrf_token标签的页面中,相应会自动设置一个cookie  csrftoken

当我们提交的时候,会自动验证csrftoken,验证通过正常执行,验证不通过就403



算法

————————————————————————————————————————————

编码算法:Base64    Unicode

摘要算法,指纹算法,杂凑算法:MD5   SHA   单向不可逆

           不管输入多长,输出都是固定长度

          MD5默认是128位的二进制(会转换成32位的16进制,然后转换为32位的Unicodde码)

只要输入有任意的变更,输出都会发生巨大的变化。

加密算法:

对称加密:一把钥匙,DES,AES

效率高,一旦钥匙全部丢失,数据就没了

非对称加密:两把钥匙,成对的,公钥1024位和私钥2048位(RSA和PGP)

算法复杂,需要时间长。支付宝、微信都是RSA


编码

————————————————————

ASCII  最开始128个,最新版256个,存英文和一些字符

Unicode  国际化


与前端对接遇到的问题(跨域请求)

————————————————————

本来我把项目部署上去了,直接访问也没有问题,然后前端就扔给我一个报错:

Access to XMLHttpRequest at 'url' from origin 'null' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.

这个报错是后端设置了防跨域请求导致的。

最开始采用安装别人的中间件的方法,没有解决,最后是自己写了个中间件解决的。

找到一个app,在其目录下创建一个Python文件:Middleware.py

然后在里面写:

class TestMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        response["Access-Control-Allow-Origin"] = "*"
        return response


即可。

最后在settings.py里面导入这个中间件,就可以生效了。

导入的时候别忘了名字后面有一个逗号,否则会出错。

另外前端测试跨域可以直接在控制台进行测试:

fetch("http://test.miao").then(res =>res.text()).then(res =>console.log(res));


其中test.miao换成你要测试的接口的URL

本文作者:赵苦瓜      文章标题: 【点滴记录】Django框架的入门 - 第五篇(会话技术、CSRF)
本文地址:https://blog.jixiaob.cn/?post=44
版权声明:若无注明,本文皆为“赵苦瓜のBlog~”原创,转载请保留文章出处。

返回顶部    首页    后花园  
版权所有:赵苦瓜のBlog~    站长: 赵苦瓜    程序:emlog   鲁ICP备20030743号-1   鲁公网安备37048102006726 萌ICP备20222268号    sitemap