会話の原則

HTTPセッションの原理説明と応用

1.会話とは

     首先解释一下什么是会话。在计算机术语中,会话是指一个终端用户与交互系统进行通讯的过程,比如从输入账户密码进入操作系统到退出操作系统就是一个会话过程。会话较多用于网络上,TCP的三次握手就创建了一个会话,TCP关闭连接就是关闭会话。用平述的语言可以解释为:你拔打你女友的电话号码,你女友接听,然后一翻“亲爱的”,直到任何一方挂掉电话,这个过程就是一个会话。你挑逗一只小狗,它跟你互动,也是会话;它不鸟你,那就不形成会话。

次に、HTTPセッションとは何ですか

プロトコルの状態とは、次回の送信で今回送信された情報を「記憶」する機能を指します。HTTPは、この接続によって送信された情報を次の接続のために維持しません。従来のWEBの観点から:ステートレスとは、ブラウザがサーバーにリクエストを送信するとサーバーが応答し、同じブラウザがサーバーにリクエストを送信すると応答することを意味しますが、彼はあなたが閲覧しているだけであることを知りません。簡単に言うと、サーバーはユーザーを記憶していないため、ステートレスプロトコルです。本質は次のとおりです。HTTP1.0は短い接続です(ここではHTTP1.1の存続を無視します)。要求が応答された後、TCP接続は切断され、次の接続は前の接続とは関係ありません。異なる要求が同じクライアントからのものであるかどうかを識別するために、HTTPセッションメカニズムが使用されます。つまり、ユーザーと、複数のHTTP接続間で同じユーザーによって発行された異なる要求との間の関連付けを維持することをセッションの維持と呼びます。セッション管理を通じて、セッションを作成、保存、クローズなどします。

三、HTTPセッションの実現メカニズム

   Cookie与session是各种教材,网上文章所介绍到的与HTTP会话相关的两个内容。这种者较常见的解释是:cookie存在在浏览器,session存储在服务器中。这种解释是最显浅的,很不严谨,但又不能说是错误。先从cookie谈起吧,很久很久以前,为了完成HTTP会话,那些互联网的设计者们想到了一个办法,就是在浏览器中存储用户信息,每次请求都向服务端发送这些信息,这样服务端就知道请求发送者是谁了,就知道应该返回什么信息给客户了。但是问题很快就出现了,张三冒充李四的名字发送请求给服务器,服务器把李四的相关信息发给了张三。为了安全起见,互联网老大哥们又想到了一招识别用户身份的办法,就是把客户信息存储在服务端(session),一切用户的身份由服务器指定。直到目前,session已成功HTTP会话的主流,应该说是绝对控制的地位。

     Session是怎样做到会话身份识别的呢?首先,用户端向服务端发送一个请求,服务端接收到请求(这里忽悠无须会话控制的情况)后,初始化会话,生成相应的会话信息,核心是会话ID,把会话ID发送给客户端,客户端接收到这个会话ID,把它存储起来,下一次发送请求的时候,附带着这个会话ID一起发送给服务端,服务端只要根据这个会话ID,就知道是谁了。这个会话ID,就像我们的身份证号码,一直伴随终生。核心:服务端如何生成这个会话ID,客户端怎样存储这个会话ID。

第四に、セッションID(SESSION ID)の保存方法

     服务端存储会话ID有多种方式,常见的有本地存储,如:普通文本,文本名就是会话ID。对于文件系统,同一目录下,同一文件名只允许唯一一个文件,那么使用会话ID作为文件名是可以做到唯一确定会话的。除了本地文件存储,还可以使用memcache、redis、或者Mysql之类的数据库存储,即使用第三方数据库进行存储。只有一个原则:存储的会话ID必须是唯一的。

     客户端收到服务端返回的(或者说服务端下发的)会话ID后,也是像服务端那样使用文件名作为会话ID存储会话信息到文本吗?如果客户端只与同一个服务端(理解为同一个服务端处理程序)进行会话通讯的话,是可行的。但是,HTTP是因万维网而生的,浏览器作为最常见的HTTP客户端,需要访问各种不同的网站,如果采用会话ID作为文件名,以这样的文件存在会话信息的话,会出现这样的情况:N个不同的网站,服务端采用的是相同的会话生成算法,在同一时刻,很可能会生成一样的会话ID,客户端则无法唯一确定这个会话ID到底是与哪个服务端通讯,也就是客户端“不认得”服务端了,会话就无法完成。如何确定服务端身份?那就是使用“域”,不同的域拥有独立的会话。客户端以域相关信息作为文件标识符创建会话文件(客户端存储)对会话信息进行存储,其中域与会话ID结合就能唯一确定服务端,并且确定会话。那么,以“域”信息作为文件名的文件中存储着会话ID等信息。每次请求某个域的服务时,把存储着的会话ID附带到请求中发送到服务端。浏览器是最常见的HTTP客户端,浏览器存储会话信息,是使用COOKIE文件的,里面保存着COOKIE信息,而服务端返回的会话ID也存储在里面。会话ID存储在COOKIE文件中是一般情况下的,而COOKIE信息是作为HTTP头发送给服务端的,也就是说这种情况下,会话ID是附带在请求头中。但是,HTTP请求,除了头信息,还可以有内容体,必须有URL。那么,会话ID同样可以存储在内容体中或URL中,比如在禁用浏览器COOKIE的情况下,也可实现与服务端会话,要么依赖内容体,要么依赖URL,常见的是URL中附带会话ID,这个在PHP等编程语言中较为常见(曾经的历史上常见,但是会涉及安全或者效率等问题,这里不详述)。

大まかに言うと、サーバーからクライアントに返されるセッションIDはCOOKIEファイルに格納されていることがわかります。クッキーファイルはブラウザで管理します。もちろん、自己実装型クライアントでは、プログラミング手段、つまりクライアントセッションの管理によってクッキーファイルの管理を実現できます。例:IOS開発者は、HTTPによって返された情報ヘッダーを管理用のサンドボックスに保存できます。PHPを使用してクライアントを開発する場合、情報ヘッダーをファイル、サードパーティサービス、またはネットワークストレージなどに書き込むことができます。

5、セッション管理(SESSION)

     会话管理包括:会话创建、会话识别、会话信息操作、会话生命周期、会话关闭。

注:このセクションのサーバーセッションはオープンと見なされ、特に指定されていない限り説明されません。

1.セッションの作成

クライアントはセッションID(SESSION ID)なしでHTTP要求を開始し、サーバーはセッションがまだ生成されていないと見なします。つまり、セッションを作成し、セッションIDを生成して関連するセッション情報をサーバーに格納し、セッションが開かれたことをクライアントに通知します。通常、セッションIDは、クライアントに返されるHTTPヘッダーのCOOKIEアイテムに、セッションタグ:セッションIDの形式で添付されます。クライアントは、返された情報ヘッダーに従ってローカルCOOKIE値を設定および保存します。

2.セッション認識

セッションIDは、セッションの一意の識別子です。ID番号が1人だけに対応するのと同様に、セッションIDは1つのセッションにのみ対応できます。HTTPでは、サーバーはパッシブに要求を受け入れ、セッション認識もパッシブ(トリガー)になります。サーバーは、誰が要求を送信しているかを知る必要はありません。相手から送信されたセッションIDを知っているだけで、クライアントから渡されたセッションIDをサーバーに保存されているセッションIDと照合できます。セッションIDが見つからない場合は、セッションが存在しないと見なされます。

例:サーバーのセッションIDは「21412545jladfjljljqwr」で、マップされた値は「名前:張さん、性別:男性」です。リクエストのセッションIDが「21412545jladfjljljqwr」である限り、クライアントはセッションを認識し、この人物が張さんと男性であると考えることができます。クライアントから要求されたセッションIDが「qwesadfasdfadsfasdf」の場合、クライアントが「名前:張さん、性別:男性」というメッセージを添付しても、サーバーはそのような人がいないと判断し、セッションは形成されません。LiSiがZhangSanのセッションIDを盗んだ場合でも、サーバーはセッションを認識します。

簡単に言うと、SESSIONはSESSION IDに基づいてセッションを確立するだけであり、セキュリティ検証には責任を負いません。サーバーとクライアントに「会話」を許可することだけに責任があります。

3.セッション情報操作

サーバー:セッションIDマッピング情報、IDは変更されておらず、マッピングの内容は可変です

クライアント:セッションIDマッピング情報、IDは変更されず、マッピングの内容は可変です(つまり、COOKIEkの内容は可変です)。

サーバーとクライアント間のセッション情報のセッションIDのみが同じである必要があり、他のセッション情報(つまり、セッションIDにマップされた情報)は直接の関係はありません。

4.セッションのライフサイクル

セッションのライフサイクルは最初から最後までです。時間を設定すると、この時間内に通信がない場合はセッション情報がクリアされます。今回をセッションタイムアウト期間と呼びます。

従来、セッションタイムアウト期間をセッションライフサイクルと呼びます。実際、これらは2つの概念です。

5.セッションは終了します

セッションを閉じるには2つの方法があります。1つは、ユーザーが積極的にセッション情報をクリアすることであり、もう1つはセッションタイムアウトです。セッションタイムアウトはガードタスク(または自動タスク)によって定期的に処理されませんが、セッション情報にアクセスするときに、セッション情報の「最終更新時間」から現在までの時間差に応じて、セッション期間と比較して、期間が期間を超えると、セッションがクリアされます。メッセージ、つまりセッションが閉じられます。

经典例子:会话过程中,突然断网。

第六に、セッション検証とHTTPプロトコルの同一性

HTTPの独立性の簡単な説明:

定義の観点から、HTTPメソッドの同一性は、特定のリソースに対する1回または複数回の要求が同じ副作用を持つはずであることを意味します。独立性はセマンティクスのカテゴリに属します。コンパイラが構文エラーのチェックのみを支援できるように、HTTP仕様には、メッセージ形式などの構文手段を使用してそれを定義する方法がありません。これが、それが真剣に受け止められない理由の1つである可能性があります。しかし実際には、独立性は分散システム設計において非常に重要な概念であり、HTTPの分散性もHTTPにおけるその重要な位置を決定します。

例(インターネットからの抜粋):アカウントからお金を引き出すためのリモートAPIがあるとします(HTTPの場合もそうでない場合もあります)。一時的にクラス関数を使用して、bool withdraw(account_id、amount)として記録します。account_idの量を減らすようにサーバーに要求し、成功した場合はtrueを返し、量が失敗した場合はfalseを返します。

     如果服务端成功了,并返回true,但网络中断,客户端收不到信息,客户端认为取钱失败,再次请求,服务端再一次扣费。这里就涉及一个重复请求同一操作的问题了。

ここに写真の説明を挿入

この問題を解決するために、撤回を同じように設計することができます。create_ticketのセマンティクスは、サーバーによって生成された一意のticket_idを取得することです。これは、後続の操作を識別するために使用されます。idempotent_withdrawとwithdrawの違いは、ticket_idが関連付けられており、ticket_idで表される操作は一度だけ処理され、各呼び出しは最初の呼び出しの処理結果を返すことです。このようにして、idempotent_withdrawはidempotenceに準拠し、クライアントはそれを複数回安全に呼び出すことができます。

ここに写真の説明を挿入

上記の例から、create_cicketの役割はID識別コードを生成することであり、後続の操作はこのIDに基づいていることがわかります。セッションIDも本質的に同一です。IDが生成された後、後続の操作はすべてIDパラメーターを持ちます。つまり、操作情報とIDの間の対応する関係が確立されます。上記の例は安全ではありません。操作が同じ人に固有であることを保証するだけです(セッションプロセス)。同様に、セッションIDは一意のIDとしてのみ使用され、セキュリティを保証するものではありません。

簡単なセッション検証:

     一种较简单的会话校验是使用令牌,即请求中除了会话ID,至少还携带了令牌。服务端对令牌校验。令牌由服务端根据某种算法生成,令牌校验也在服务端中处理,客户端只需存储令牌,在请求中携带令牌,令牌生成算法的复杂程度影响令牌校验的安全性。

例:tokenFunc(param、value = '')最初のパラメーターはトークン生成パラメーターで、2番目のパラメーターはトークン値です。2番目のパラメーターが空の場合、トークンが生成され、文字列が返されます。2番目のパラメーターが空でない場合、トークンの精度がチェックされ、boolが返されます。通常、ハッシュが暗号化されている限り、復号化は必要ありません。PHPコードは次のとおりです。

関数token(param、param、p a r a m value = ''){

     if(!is_string($param){

     $param = serialize($param);

}

トークン= md 5(トークン= md5( t o k e n=m d 5 param.'sault ');

if(!empty($ value)){

     if($value == $token){

     return true;

}そうしないと{

     return false;

}

}そうしないと{

     return $token;

}

}

トークンを生成します:token = token(token = token(t o k e n=t o k e n session_id);

トークンを確認してください:check = token(check = token(c h e c k=t o k e n session_id、$ token);

セブン、会話の原則の適用

ブラウザはデフォルトでCookieをオンにします。ブラウザがHTTPリクエストを開始すると、リクエストヘッダーにCookie情報が含まれます。サーバーがSessionIDを含むCookieを返す限り、サーバーはSessionidに基づいてHTTPセッションを実現します。このプロセスはフロントエンド開発者向けです。透過的(つまり、フロントエンド開発は、ブラウザーがサーバーとの会話をどのように決定するかを気にしません)。

     除即时通讯,实时动作网游外,大多APP是使用HTTP协议与服务端通讯的,使用HTTP协议的原因主要是移动网络环境复杂(容易断线),并且HTTP协议穿透性强。原生开发的IOS,安卓等APP,与服务端会话,可不使用COOKIE,只需要在请求中携带会话ID即可,这在上文已描述。原生APP与内嵌浏览器的APP相比:原生实现性能更高,交互效果流畅,用户体验相对较好,但快速跌代比不上内嵌浏览器的APP。手机配置越来越高,内嵌浏览器对HTML5支持也越来越好,在性能要求不是很高的场景,内嵌WEB的性能已可满足,在布局多变,或者元素多变的情况下,可快速修改,而无需用户升级APP,也能获得更好的产品体验。APP内嵌WEB最常见的场景就是电商APP了,登陆、注册、入口等交互效果较多的模块使用原生程序开发,而商品列表、商品展示等等模块可采用内嵌WEB,这样既可满足快速产品跌代的要求,又可满足操作的性能要求。

     举例:电商APP入门界面、登陆、注册是使用原生开发的,登陆后跳转到商品列表页(即内嵌WEB),然后下订单。问题来了,如何使得登陆后跳转到WEB后,还是登陆状态(即内嵌WEB与原生程序具有一致的会话 )呢?内嵌WEB是不会去取得原生程序所存储的data的。最简单直接的办法就是:登陆成功,服务器返回会话ID与成功信息,跳转到WEB时,发送的HTTP请求头中包括COOKIE,会话ID存储在COOKIE中,这样之后点击WEB中的链接后向服务端发送的HTTP请求头,就会携带这个COOKIE(会话ID)了。简单地理解:终端原生程序请求服务端,服务端按普通WEB那样返回信息,终端原生程序取得HTTP返回头中的COOKIE信息,保存下来,下一次请求时,携带COOKIE信息即可。在浏览器中,COOKIE的处理由浏览器默认处理,而在原生APP程序中,由开发者写程序去处理而已。

おすすめ

転載: blog.csdn.net/weixin_39380337/article/details/84261351