上一篇主要讲了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
本文地址:https://blog.jixiaob.cn/?post=44
版权声明:若无注明,本文皆为“赵苦瓜のBlog~”原创,转载请保留文章出处。