Djangoの基礎クッキーとセッション
1.セッショントラッキング
会話は何ですか!会話は、複数の要求と応答を含むことができ、会議中に、クライアントとサーバの間の会合として理解することができます。たとえば、10086には、クライアントだ、電話をかける、と10086サービスは、サーバです。瞬間から双方が電話を接続するため、セッションが電話を切るするか、始まったセッションの終わりを示します。単一のセッションでそのように複数の要求通話中に、それは、10086に複数のリクエストが発行されます。最初のクライアントがセッションを開始するためにサーバに要求を送信し、顧客の終わりには、ブラウザセッションを閉じまで、始まりました。
2.cookie
クッキーの起源
HTTPプロトコル
超文本传输协议
关于连接:一次请求一次响应之后断开连接(无状态,短连接)
关于格式:(请求头内容之间用\r\n,请求头和请求体之间\r\n\r\n,响应同理)
请求:请求头+请求体
响应:响应头+响应体
拓展:
常见的请求头:1.user-agent:用的什么浏览器访问的网站
2.content-type:请求体的数据格式(服务端按照格式进行解析)
ステートレス手段は、各リクエストの独立しており、要求前のインプリメンテーションに、結果が直接関連していない後ではなく、上記ケース要求各直接的な影響による要求は、そのままバックに影響を与えません適切な状況を要求する。状態はステートレス、特定のセッションで生成されたクライアントとサーバーの両方のデータとして理解し、これらのデータは保持されないことを考えることができる。データ生成したセッションはそれがであり、私たちは保存する必要があるということです「ホールド」、したがって、このようなクッキーが生成されます
クッキーとは何ですか
クッキーは、ブラウザ技術で、具体的に言及クッキーは、サーバーように、それは、ブラウザの右側に保存されているキーのセットを送信し、サーバーのブラウザにアクセスする次の時間が自動的にこれらのキーと値のペアを運ぶサーバーで、ほとんど情報でした有用な情報を抽出します
原則クッキー
、ブラウザの訪問は、ブラウザが自動的にクッキーを持って来るときに、ブラウザが空のクッキーで、サーバーにアクセスし、サーバーからコンテンツを生成するために、ブラウザは、ローカルに保存された応答を受け取る:あるクッキーがワークスように、サーバーはクッキーの内容を判断することができるようになります。
クッキーのイラスト
クッキーの仕様
- クッキーのサイズが4KBの限界です。
- クライアントブラウザ上のクッキー20まで保存サーバー。
- ブラウザが複数のサーバにアクセスすることができますので、ブラウザは、300クッキーまで保存します。
上記のデータは、HTTPクッキー仕様ですが、今日のブラウザ戦争では、ブラウザのいくつかの能力を示すために、相手を倒すためには、そのような各クッキーの大きさなど、いくつかは、8キロバイトである「拡張」のためかもしれないクッキーの仕様、最も500クッキーなどを保存することができます!しかし、それはあなたのハードドライブが表示されません埋めること!
なお、異なるブラウザはクッキーの共有されていません。これは、サーバーにアクセスするためにIEを使用する場合、サーバはIEのCookieが送信されます、そしてあなたは、Firefox、IEを使用してサーバがサーバに保存されたクッキーを送信することはできませんアクセスしたときにアップIEを保存しています。
クッキーやHTTPヘッダ
クッキーは、HTTPリクエストとレスポンスヘッダークライアントとサーバから送信されています。
- クッキー:クライアントからサーバに送られたリクエスト・ヘッダー。
- フォーマット:クッキー:= A; B = B; C = C. すなわち、離れたクッキーセミコロンの複数から;のSet-Cookie:レスポンスのヘッダには、サーバーがクライアントに送信します。
- セット - クッキー:クッキーのSet-CookieオブジェクトA = AのSet-Cookie:B = BのSet-Cookie:C = C
クッキーのカバレッジ
もし、サーバ、その後送信クッキーが古いクッキーが上書きされます繰り返し、例えば、サーバから送信された最初のクライアント要求は、クッキーです:のSet-Cookie:A = A; 2番目の要求はサーバによって送信されます。Set-Cookieの:のみクッキーを残し、その後= AA、クライアント、すなわち:A = AA。
3.django操作クッキー
ページキャッシュとクッキーをクリアするには、Ctrl + Shiftキー+デル3つのキー
クッキーの取得
request.COOKIES['key']
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
パラメータ:
- デフォルト:デフォルト値
- 塩:塩暗号化
- max_ageの:バックグラウンドコントロールの有効期限
設定されたCookie
rep = HttpResponse(...)
rep = render(request, ...)
rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt='加密盐', max_age=None, ...)
パラメータ:
- キー、キー
- 値=「」の値
- max_ageの=なし、タイムアウト
- =いずれも有効期限が切れていない、超时时间(IEはまだされていない場合ので、それを設定し、満了が必要です。)
- 力のクッキーパスに入力されたパスは=「/」、/ルートパスを表し、特別:クッキーのルートパスは、ページの任意のURLにアクセスすることができます
- 力へのドメインのドメイン=なし、クッキー
- 安全な= Falseを、HTTPSの送信
- HTTPのみ= FalseのHTTPプロトコルのみ輸送、JavaScriptが取得できない(絶対的ではないが、キャプチャの底に取得することができます覆われていてもよいです)
set_cookie方法出典
class HttpResponseBase:
def set_cookie(self, key, #键
value='', #值
max_age=None, #超长时间 ,有效事件,max_age=20意思是这个cookie20秒后就消失了,默认时长是2周,这个是以秒为单位的
#cookie需要延续的时间(以秒为单位)如果参数是\ None`` ,这个cookie会延续到浏览器关闭为止。
expires=None, #超长时间,值是一个datetime类型的时间日期对象,到这个日期就失效的意思,用的不多,expires默认None ,cookie失效的实际日期/时间。
path='/', #Cookie生效的路径,就是访问哪个路径可以得到cookie,'/'是所有路径都能获得cookie,浏览器只会把cookie回传给带有该路径的页面,这样可以避免将,cookie传给站点中的其他的应用。/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问
domain=None, #Cookie生效的域名你可用这个参数来构造一个跨站cookie。如, domain=".example.com"所构造的cookie对下面这些站点都是可读的:www.example.com 、 www2.example.com和an.other.sub.domain.example.com 。如果该参数设置为 None ,cookie只能由设置它的站点读取。
secure=False, #如果设置为 True ,浏览器将通过HTTPS来回传cookie。
httponly=False # 只能http协议传输,无法被JavaScript获取,不是绝对,底层抓包可以获取到也可以被覆盖)
): pass
クッキーを削除します。
def logout(request):
rep = redirect("/login/")
rep.delete_cookie("user") # 删除用户浏览器上之前设置的usercookie值
return rep
クッキーログインチェックの例
def check_login(func):
@wraps(func)
def inner(request, *args, **kwargs):
next_url = request.get_full_path()
if request.get_signed_cookie("login", salt="SSS", default=None) == "yes":
# 已经登录的用户...
return func(request, *args, **kwargs)
else:
# 没有登录的用户,跳转刚到登录页面
return redirect("/login/?next={}".format(next_url))
return inner
def login(request):
if request.method == "POST":
username = request.POST.get("username")
passwd = request.POST.get("password")
if username == "xxx" and passwd == "dashabi":
next_url = request.GET.get("next")
if next_url and next_url != "/logout/":
response = redirect(next_url)
else:
response = redirect("/class_list/")
response.set_signed_cookie("login", "yes", salt="SSS")
return response
return render(request, "login.html")
4.session
セッションはサーバー側の技術、この技術の使用で、サーバーが原因、ユーザーのブラウザセッションに、その排他の各ユーザーのブラウザセッションオブジェクトの実行時に作成することができ、排他的なので、ユーザーがWebサーバーのリソースにアクセスすると、ユーザー・アクセス他のWebリソースは、サーバーに移動し、他のWebリソースを削除するときには、それぞれのデータセッション中に配置することができ、それぞれのユーザーセッションからユーザサービスデータ。
クッキーがある程度解決しますが、要件を「ホールド」が、4096バイトの最大サポート自体クッキー、クッキーやクライアント自体に保存されているため、傍受または盗難することができるため、したがって、何か新しいものが必要とされて、それをより多くのバイトをサポートする、と彼は、サーバー上に保存され、高いセキュリティがあります。これはセッションです。
質問は「誰が。」サーバは、訪問者を知らない、ステートレスなHTTPプロトコルの特性に基づいて、あります そして、前述したクッキーは、ブリッジの役割を果たします。
私たちは、ユーザーがクッキーでアクセスするように、サーバは人々に知っている、割り当てられた固有のIDを各クライアントのクッキーを与えることができます「」その後、我々、このような「アカウントのパスワード」など、いくつかの時間のためにサーバーに保存されているクッキーの、プライベートな情報に基づいて異なるID、というように。
結論:クッキーまでステートレス不足HTTPのために、サーバは「」人々に知らせて、テキスト形式のクッキーは、ローカルに保存されているが、彼らのセキュリティが貧弱であり、私たちは別のクッキーを介してユーザを識別することができ、セッションで4096バイトより個人情報及びテキストの保存に対応します。
さらに、上記の事実は、クッキーとセッション共通のものは、ない言語やフレームに制限されています。
5.djangoの操作セッション
セッション関連する方法
注:このメソッドは、ジャンゴによって提供され、フレームワークは、あなた自身のクッキーとのセッションに他の方法が必要になります。
# 获取、设置、删除Session中数据#取值
request.session['k1']
request.session.get('k1',None) #request.session这句是帮你从cookie里面将sessionid的值取出来,将django-session表里面的对应sessionid的值的那条记录中的session-data字段的数据给你拿出来(并解密),get方法就取出k1这个键对应的值#设置值
request.session['k1'] = 123
request.session.setdefault('k1',123) # 存在则不设置
#帮你生成随机字符串,帮你将这个随机字符串和用户数据(加密后)和过期时间保存到了django-session表里面,帮你将这个随机字符串以sessionid:随机字符串的形式添加到cookie里面返回给浏览器,这个sessionid名字是可以改的
#但是注意一个事情,django-session这个表,你不能通过orm来直接控制,因为你的models.py里面没有这个对应关系
#删除值
del request.session['k1'] #django-session表里面同步删除
# 所有 键、值、键值对
request.session.keys()
request.session.values()
request.session.items()
# 会话session的key
session_key = request.session.session_key 获取sessionid的值
# 将所有Session失效日期小于当前日期的数据删除,将过期的删除
request.session.clear_expired()
# 检查会话session的key在数据库中是否存在
request.session.exists("session_key") #session_key就是那个sessionid的值
# 删除当前会话的所有Session数据
request.session.delete()
# 删除当前的会话数据并删除会话的Cookie。
request.session.flush() #常用,清空所有cookie---删除session表里的这个会话的记录,
这用于确保前面的会话数据不可以再次被用户的浏览器访问
例如,django.contrib.auth.logout() 函数中就会调用它。
# 设置会话Session和Cookie的超时时间
request.session.set_expiry(value)
* 如果value是个整数,session会在些秒数后失效。
* 如果value是个datatime或timedelta,session就会在这个时间后失效。
* 如果value是0,用户关闭浏览器session就会失效。
* 如果value是None,session会依赖全局session失效策略。
セッション詳細なフロー分析
セッションログインの検証例
from functools import wraps
def check_login(func):
@wraps(func)
def inner(request, *args, **kwargs):
next_url = request.get_full_path()
if request.session.get("user"):
return func(request, *args, **kwargs)
else:
return redirect("/login/?next={}".format(next_url))
return inner
def login(request):
if request.method == "POST":
user = request.POST.get("user")
pwd = request.POST.get("pwd")
if user == "alex" and pwd == "alex1234":
# 设置session
request.session["user"] = user
# 获取跳到登陆页面之前的URL
next_url = request.GET.get("next")
# 如果有,就跳转回登陆之前的URL
if next_url:
return redirect(next_url)
# 否则默认跳转到index页面
else:
return redirect("/index/")
return render(request, "login.html")
@check_login
def logout(request):
# 删除所有当前请求相关的session
request.session.delete()
return redirect("/login/")
@check_login
def index(request):
current_user = request.session.get("user", None)
return render(request, "index.html", {"user": current_user})
问题:同一个浏览器上,如果一个用户已经登陆了,你如果在通过这个浏览器以另外一个用户来登陆,那么到底是第一个用户的页面还是第二个用户的页面,有同学是不是懵逼了,你想想,一个浏览器和一个网站能保持两个用户的对话吗?你登陆一下博客园试试,第一个用户登陆的时候,没有带着sessionid,第二个用户登陆的时候,带着第一个用户的sessionid,这个值在第二个用户登陆之后,session就被覆盖了,浏览器上的sessionid就是我第二个用户的了,那么你用第一个用户再点击其他内容,你会发现,看到的都是第二个用户的信息(注意:公众都能访问的a标签不算)。还有,你想想是不是你登陆一次就在django-session表里面给你添加一条session记录吗?为什么呢?因为你想,如果是每个用户每次登陆都添加一条sesson的记录,那么这个用户一年要登陆多少次啊,那你需要记录多少次啊,你想想,所以,你每次登陆的时候,都会将你之前登陆的那个session记录给你更新掉,也就是说你登陆的时候,如果你带着一个session_id,那么不是新添加一条记录,用的还是django-session表里面的前面那一次登陆的session_key随机字符串,但是session_data和expire_date都变了,也就是说那条记录的钥匙还是它,但是数据变了,有同学又要问了,那我过了好久才过来再登陆的,那个session_id都没有了啊怎么办,你放心,你浏览器上的session_id没有了的话,你django-session表里的关于你这个用户的session记录肯定被删掉了。再想,登陆之后,你把登陆之后的网址拿到另外一个浏览器上去访问,能访问吗?当然不能啦,另外一个浏览器上有你这个浏览器上的cookie吗,没有cookie能有session吗?如果你再另外一个浏览器上又输入了用户名和密码登陆了,会发生什么事情,django-session表里面会多一条记录,记着,一个网站对一个浏览器,是一个sessionid的,换一个浏览器客户端,肯定会生成另外一个sessionid,django-session表里面的session_key肯定不同,但是session_data字段的数据肯定是一样的,当然了,这个还要看人家的加密规则。
ジャンゴでのセッション構成
Djangoのデフォルトサポートのセッションは、その内部には、使用する開発者のためのセッションの5種類を提供しています。
1. 数据库Session
SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认)
2. 缓存Session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎
SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
3. 文件Session
SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎
SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()
4. 缓存+数据库
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎
5. 加密Cookie Session
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
# 引擎
其他公用设置项:
SESSION_COOKIE_NAME = "sessionid"
# Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
SESSION_COOKIE_PATH = "/"
# Session的cookie保存的路径(默认)
SESSION_COOKIE_DOMAIN = None
# Session的cookie保存的域名(默认)
SESSION_COOKIE_SECURE = False
# 是否Https传输cookie(默认)
SESSION_COOKIE_HTTPONLY = True
# 是否Session的cookie只支持http传输(默认)
SESSION_COOKIE_AGE = 1209600
# Session的cookie失效日期(2周)(默认)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
# 是否关闭浏览器使得Session过期(默认)
SESSION_SAVE_EVERY_REQUEST = False
# 是否每次请求都保存Session,默认修改之后才保存(默认)