Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cookie session杂谈 #8

Open
39Er opened this issue May 10, 2017 · 1 comment
Open

cookie session杂谈 #8

39Er opened this issue May 10, 2017 · 1 comment

Comments

@39Er
Copy link
Owner

39Er commented May 10, 2017

what is cookie ?

    通俗的讲就是一个用户通过http协议访问一个服务器的时候,这个服务器会将一些key/value键值对返回给客户端浏览器,并给这些数据加上一些限制条件,在条件符合时这个用户下次访问这个服务器的时候,数据又被完整的带回给服务器。

set cookie: name=value; domain=.mozilla.org; expires=Feb, 13-Mar-2018 11:47:50; path=/; secure

  • Domain:域,表示当前cookie所属于哪个域或子域下面。

    此处需要额外注意的是,在C#中,如果一个cookie不设置对应的Domain,那么在CookieContainer.Add(cookies)的时候,会死掉。对于服务器返回的Set-Cookie中,如果没有指定Domain的值,那么其Domain的值是默认为当前所提交的http的请求所对应的主域名的。比如访问 [http://www.example.com],返回一个cookie,没有指名domain值,那么其为值为默认的www.example.com。

  • Path:表示cookie的所属路径。
  • Expire time/Max-age:表示了cookie的有效期。expire的值,是一个时间,过了这个时间,该cookie就失效了。或者是用max-age指定当前cookie是在多长时间之后而失效。如果服务器返回的一个cookie,没有指定其expire time,那么表明此cookie有效期只是当前的session,即是session cookie,当前session会话结束后,就过期了。对应的,当关闭(浏览器中)该页面的时候,此cookie就应该被浏览器所删除了。
  • secure:表示该cookie只能用https传输。一般用于包含认证信息的cookie,要求传输此cookie的时候,必须用https传输。
  • httponly:表示此cookie必须用于http或https传输。这意味着,浏览器脚本,比如javascript中,是不允许访问操作此cookie的。

发向服务器的所有 cookie 的最大数量(空间)仍旧维持原始规范中所指出的:4KB。所有超出该限制的 cookie 都会被截掉并且不会发送至服务器。

由于cookie存在客户端,可能被篡改。

cookie本身并没有会话cookie和持久化cookie之分,只是取决于是否设置了存活时间。

cookie-parser

cookie parsing middleware: github地址

Installation

$ npm install cookie-parser

API

var express = require('express')
var cookieParser = require('cookie-parser')

var app = express()
app.use(cookieParser())

cookieParser(secret, options)

secret:(String/Array)签名cookie,不指定则不会解析signed cookie

options:

    decode: 用于解码cookie值的方法,默认为decodeURIComponent

what is session ?

    session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。

session 可以存放在 1)内存、2)cookie本身、3)redis 或 memcached 等缓存中,或者4)数据库中。

Express Session

github 地址

Installation

$ npm install express-session

var session = require('express-session')

session(option)

  • cookie: cookie的相关属性设置,默认为:{ path: '/', httpOnly: true, secure: false, maxAge: null }
  • genid: 用于生成新的session id的方法
  • name: cookie中session Id的名字,默认为:connect.sid
  • proxy: 当设置安全cookie时,信任反向代理
  • resave: 即使request.session没有变化,也强制将session再保存到store中
  • rolling: 强制在每个响应中设置session id cookie
  • saveUninitialized: 强制将未初始化的session保存到store中
  • secret(required option)用于session id cookie签名
  • store(default:MemoryStore,通常使用redis)
  • unset

将session存储在redis中,可实现不同服务间的session共享

connect-redis

redis store : github地址(又见TJ...)

node-redis

redis client : github地址

我的相关代码:

const cookieParser = require('cookie-parser'); 
const session = require('express-session');
const redisStore = require('connect-redis')(session);
const redis = require('redis'); 

//connect redis   
const redisClient = redis.createClient(); 
redisClient.on('error',function(err){ 
  logger.error(err);  
  process.exit(1);
});
app.use(cookieParser());  
app.use(session({ 
  store: new redisStore({ 
client:redisClient
  }), 
  secret: 'ACDataServer', 
  cookie: {   
maxAge: 12*60*60*1000 
  },  
  proxy: true,
  saveUninitialized: true,
  resave: false   
}));                    

cookie被禁用处理方法

由于cookie可以被人为的禁止,必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。

  • 经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面,附加方式也有两种:

        一种是作为URL路径的附加信息,表现形式为http://...../xxx;jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764

        另一种是作为查询字符串附加在URL后面,表现形式为http://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764

    这两种方式对于用户来说是没有区别的,只是服务器在解析的时候处理的方式不同,采用第一种方式也有利于把session id的信息和正常程序参数区分开来。

    为了在整个交互过程中始终保持状态,就必须在每个客户端可能请求的路径后面都包含这个session id。

  • 另一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。比如下面的表单

      <form name="testform" action="/xxx">
      	<input type="text">
      </form>
    
  • 在被传递给客户端之前将被改写成

      <form name="testform" action="/xxx">
      <input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
      <input type="text">
      </form>
    
@39Er
Copy link
Owner Author

39Er commented May 10, 2017

TODO: signed cookie; java cookie session

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant