1. Cookie介紹:
Cookie是保存在瀏覽器中的數(shù)據(jù)扛禽,可以讓我們?cè)谕粋€(gè)瀏覽器訪問(wèn)同一個(gè)域名時(shí)共享cookie數(shù)據(jù)鹤啡。
1.1 使用cookie,可實(shí)現(xiàn)的幾個(gè)常用場(chǎng)景:
- 保存用戶信息
- 瀏覽器歷史記錄
- 猜你喜歡
- 10天免登錄
- 多個(gè)頁(yè)面之間數(shù)據(jù)的傳遞
- cookie實(shí)現(xiàn)購(gòu)物車(chē)記錄功能
1.2 Koa中設(shè)置Cookie的值:
ctx.cookies.set(key, name, [options]);
通過(guò)key
和value
來(lái)設(shè)置cookie的鍵值羔杨;
其中options
是設(shè)置cookie時(shí)的選項(xiàng)參數(shù):
maxAge
: 毫秒數(shù)撕蔼,cookie的有效時(shí)長(zhǎng);expires
: cookie 過(guò)期的具體日期(Date值)path
: cookie 路徑,或链,默認(rèn)是'/'惫恼,只有在path
的URI中,cookie值才可獲取domain
: cookie 域名secure
: 默認(rèn)false澳盐,設(shè)置成true 表示只有https 可以訪問(wèn)httpOnly
: 默認(rèn)是true祈纯,只有服務(wù)器可訪問(wèn)cookie,瀏覽器通過(guò)javascript
不可獲取overwrite
: 是否覆蓋以前設(shè)置的同名的cookie (默認(rèn)是false)
1.3 Koa中獲取cookie的值:
ctx.cookies.get('key');
1.4 結(jié)合代碼舉例options
中參數(shù)的使用:
1.4.1 maxAge
設(shè)置cookie在瀏覽器上的過(guò)期時(shí)長(zhǎng):
router.get('/', async (ctx, next)=>{
ctx.cookies.set('userinfo', 'joyitsai', {
maxAge: 10*24*60*60*1000, /*設(shè)置cookie過(guò)期時(shí)間10天叼耙,單位ms*/
})
ctx.render('index', {});
})
訪問(wèn)主頁(yè)腕窥,查看cookie的信息,會(huì)發(fā)現(xiàn):
1.4.2expires
設(shè)置cookie具體過(guò)期日期:
router.get('/', async (ctx, next)=>{
ctx.cookies.set('userinfo', 'joyitsai', {
// new Date(year, month, day, hours, minutes, seconds, milliseconds)
/**Date()對(duì)象中實(shí)例化日期時(shí)筛婉,月份為0~11簇爆,5即表示6月 */
expires: new Date(2019, 5, 1, 10, 40, 0, 0),
})
ctx.render('index', {});
})
查看cookie信息如下:
1.4.3 path
設(shè)置cookie的有效路徑:
router.get('/', async (ctx, next)=>{
ctx.cookies.set('userinfo', 'joyitsai', {
// new Date(year, month, day, hours, minutes, seconds, milliseconds)
expires: new Date(2019, 5, 1, 10, 40, 0, 0),
path: '/user', /**只在/user路徑下有效 */
})
ctx.render('index', {});
});
router.get('/user', async(ctx, next)=>{
/*ctx.cookies.get()獲取cookie信息*/
ctx.body = `${ctx.cookies.get('userinfo')}`;
})
當(dāng)訪問(wèn)localhost:3000
時(shí),會(huì)發(fā)現(xiàn)并沒(méi)有cookie信息爽撒。因?yàn)閏ookie信息只在/user
路徑下有效入蛆,再訪問(wèn)localhost:3000/user
時(shí),會(huì)看到cookie信息如下:
1.4.4 domain
設(shè)置cookie有效的域名:
domain
這個(gè)參數(shù)硕勿。通常是在你具備多個(gè)域名時(shí)哨毁,例如news.baidu.com
和baidu.com
時(shí),希望多個(gè)域名之間能夠共享cookie數(shù)據(jù)首尼,才去設(shè)置為:.baidu.com
挑庶;如果只有一個(gè)域名,不用設(shè)置软能,默認(rèn)是本機(jī)域名迎捺。
1.4.5 httpOnly
設(shè)置cookie是否只能在服務(wù)器端訪問(wèn):
在默認(rèn)為true
的情況下,在頁(yè)面的javascript代碼中調(diào)用document.cookie
:
router.get('/', async (ctx, next)=>{
ctx.cookies.set('userinfo', 'joyitsai', {
// new Date(year, month, day, hours, minutes, seconds, milliseconds)
expires: new Date(2019, 5, 1, 10, 40, 0, 0),
httpOnly: true,
})
ctx.render('index', {});
});
index.html
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script>
alert(document.cookie);
</script>
</head>
<body>
</body>
</html>
訪問(wèn)主頁(yè)面查排,會(huì)發(fā)現(xiàn)alert彈出的是空:
把上面代碼中的
httpOnly
設(shè)置為false凳枝,再訪問(wèn)會(huì)看到:請(qǐng)根據(jù)項(xiàng)目具體的需求,來(lái)設(shè)置
httpOnly
參數(shù)跋核。
1.5 Koa中設(shè)置中文的cookie:
在koa中岖瑰,cookie設(shè)置成中文時(shí)會(huì)報(bào)錯(cuò),使用base64字符串
來(lái)轉(zhuǎn)化并解析中文砂代,可以解決這個(gè)問(wèn)題:
router.get('/', async (ctx, next)=>{
let zh = new Buffer('哈哈哈').toString('base64');
console.log(zh);
ctx.cookies.set('userinfo', zh, {})
ctx.render('index', {});
});
router.get('/user', async(ctx, next)=>{
let zh_ = ctx.cookies.get('userinfo');
console.log(zh_)
let info = new Buffer(zh_, 'base64').toString();
console.log(info);
})
訪問(wèn)主頁(yè)蹋订,查看到的cookie信息為:
當(dāng)訪問(wèn)
localhost:3000/user
時(shí),獲取到的5ZOI5ZOI5ZOI
被轉(zhuǎn)換成哈哈哈
刻伊;這時(shí)露戒,就通過(guò)base64字符串
的轉(zhuǎn)換椒功,把cookie信息設(shè)置成了中文。
2. Koa項(xiàng)目中的Session:
上面解析了在Koa中cookie的相關(guān)設(shè)置和具體使用示例智什,下面再說(shuō)一下session:
- 什么是session:
session
是另一種記錄客戶狀態(tài)的機(jī)制动漾,不同的是Cookie 保存在客戶端瀏覽器中,而session
保存在服務(wù)器上荠锭。 - session的工作流程:
當(dāng)瀏覽器訪問(wèn)服務(wù)器并發(fā)送第一次請(qǐng)求時(shí)旱眯,服務(wù)器端會(huì)創(chuàng)建一個(gè)session 對(duì)象,生成一個(gè)類(lèi)似于key,value 的鍵值對(duì)证九, 然后將key(cookie)返回到瀏覽器(客戶)端删豺,瀏覽器下次再訪問(wèn)時(shí),攜帶key(cookie)甫贯,找到對(duì)應(yīng)的session(value)吼鳞,客戶的信息都保存在session 中。
關(guān)于session
的詳細(xì)流程解釋叫搁,自行百度赔桌。
2.1 安裝session:
npm install koa-session --save
2.2 引入并配置koa-session:
所謂的配置,實(shí)際上都是針對(duì)存儲(chǔ)在客戶端的cookie來(lái)進(jìn)行的渴逻,通過(guò)設(shè)置不同的參數(shù)項(xiàng)疾党,觀察瀏覽器中的cookie信息。
關(guān)于
koa-session
配置的作用機(jī)制
:
既然我們知道了惨奕,koa-session實(shí)際上是在服務(wù)端生成一個(gè)cookie:session對(duì)雪位,cookie作為session的key
發(fā)送給瀏覽器,讓瀏覽器的下次請(qǐng)求攜帶并獲取相應(yīng)的session信息梨撞。那么這個(gè)cookie實(shí)際上也是需要一定加密的雹洗,不然也是不太安全的。因此卧波,在下面的配置中:
key: 'koa:sess'
是返送給瀏覽器的cookie名时肿;app.keys=['some secret hurr']
是發(fā)送給瀏覽器cookie值時(shí)的加密數(shù)組:cookie值在服務(wù)器端依據(jù)app.keys
的數(shù)組字符串和服務(wù)器當(dāng)前時(shí)間,被signed:true
簽名(加密)成加密字符串港粱。以提升cookie值的安全性螃成。- 服務(wù)端通過(guò)解析cookie值得到cookie被生成時(shí)的時(shí)間和
app.keys
數(shù)組中的加密字符串,一旦時(shí)間超過(guò)了maxAge
則cookie失效查坪;同時(shí)一旦解析的加密字符串與app.keys
中的不符則cookie無(wú)效寸宏。
/*引入koa-session*/
const session = require('koa-session');
/*配置koa-session*/
app.keys = ['some secret hurr'];
const CONFIG = {
key: 'koa:sess', //cookie key (default is koa:sess)
maxAge: 86400000, // cookie 的過(guò)期時(shí)間maxAge in ms (default is 1 days)
overwrite: true, //是否可以overwrite (默認(rèn)default true)
httpOnly: true, //cookie 是否只有服務(wù)器端可以訪問(wèn)httpOnly or not (default true)
signed: true, //簽名默認(rèn)true
rolling: false, //在每次請(qǐng)求時(shí)強(qiáng)行設(shè)置cookie,這將重置cookie 過(guò)期時(shí)間(默認(rèn):false)
renew: true, //當(dāng)cookie快過(guò)期時(shí)請(qǐng)求,會(huì)重置cookie的過(guò)期時(shí)間
};
app.use(session(CONFIG, app));
2.3 在Koa項(xiàng)目中設(shè)置和獲取session:
/*設(shè)置session值偿曙,將保存在服務(wù)器內(nèi)存上*/
ctx.session.username = 'joyitsai';
/*獲取session的值*/
console.log(ctx.session.username);
2.4 Cookie 和Session 區(qū)別
- cookie 數(shù)據(jù)存放在客戶的瀏覽器上氮凝,session 數(shù)據(jù)放在服務(wù)器上。
- cookie 不是很安全望忆,別人可以分析存放在本地的COOKIE 并進(jìn)行COOKIE 欺騙考慮到安全應(yīng)當(dāng)使用session覆醇。
- session 會(huì)在一定時(shí)間內(nèi)保存在服務(wù)器上朵纷。當(dāng)訪問(wèn)增多炭臭,會(huì)比較占用你服務(wù)器的性能考慮到減輕服務(wù)器性能方面永脓,應(yīng)當(dāng)使用COOKIE。
- 單個(gè)cookie 保存的數(shù)據(jù)不能超過(guò)4K鞋仍,很多瀏覽器都限制一個(gè)站點(diǎn)最多保存20 個(gè)cookie常摧。