麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

cookie和session(宇宙級(jí)框架express)

2019-11-11 05:13:15
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

首先,我必須義正言辭的吐槽一下這個(gè)宇宙級(jí)框架!exPRess3.x和expss4.x差別怎么就那么大呢?找了好多資料來(lái)學(xué)習(xí),但總是莫名其妙的報(bào)錯(cuò),一開(kāi)始我以為是因?yàn)槲议L(zhǎng)得不好看,后來(lái)發(fā)現(xiàn)。。。我用的是4.x的express,而教程是3.x的,好多都對(duì)不上號(hào)。我@#¥%……&*()&……¥

好了,吐槽結(jié)束,進(jìn)入正題。作為一個(gè)勵(lì)志改變世界的程序員,我們必須緊跟時(shí)代的潮流,所以nodejs死亡筆記都是基于express4.x的。本篇文章將講解cookie和session。

我之前寫過(guò)一篇express項(xiàng)目搭建的博客,所以如何搭建我就不說(shuō)了。

在web應(yīng)用中,多個(gè)請(qǐng)求之間共享“用戶會(huì)話”是非常必要的。但HTTP1.0協(xié)議是無(wú)狀態(tài)的。那這時(shí)Cookie就出現(xiàn)了。那Cookie又是如何處理的呢?

Cookie的處理:

服務(wù)端向客戶端發(fā)送Cookie客戶端的瀏覽器把Cookie保存然后在每次請(qǐng)求瀏覽器都會(huì)將Cookie發(fā)送到服務(wù)端

在HTML文檔被發(fā)送之前,Web服務(wù)器通過(guò)傳送HTTP 包頭中的Set-Cookie 消息把一個(gè)cookie 發(fā)送到用戶的瀏覽器中,如下示例:

Set-Cookie: name=value; Path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT;11

其中比較重要的屬性:

name=value:鍵值對(duì),可以設(shè)置要保存的 Key/Value,注意這里的 name 不能和其他屬性項(xiàng)的名字一樣Expires: 過(guò)期時(shí)間(秒),在設(shè)置的某個(gè)時(shí)間點(diǎn)后該 Cookie 就會(huì)失效,如 expires=Wednesday, 09-Nov-99 23:12:40 GMTmaxAge: 最大失效時(shí)間(毫秒),設(shè)置在多少后失效secure: 當(dāng) secure 值為 true 時(shí),cookie 在 HTTP 中是無(wú)效,在 HTTPS 中才有效Path: 表示 cookie 影響到的路,如 path=/。如果路徑不能匹配時(shí),瀏覽器則不發(fā)送這個(gè)Cookie

cookie在express中的使用

express 在 4.x 版本之后,管理session和cookies等許多模塊都不再直接包含在express中, `而是需要單獨(dú)下載安裝相應(yīng)模塊。

cookieParser安裝: $ npm install cookie-parser

通過(guò)express命令創(chuàng)建的項(xiàng)目會(huì)自動(dòng)將這個(gè)模塊安裝。

使用方法:

app.get('/', function (req, res) { // 如果請(qǐng)求中的 cookie 存在 isVisit, 則輸出 cookie // 否則,設(shè)置 cookie 字段 isVisit, 并設(shè)置過(guò)期時(shí)間為1分鐘 if (req.cookies.isVisit) { console.log(req.cookies); res.send("再次歡迎訪問(wèn)"); } else { res.cookie('isVisit', 1, {maxAge: 60 * 1000}); res.send("歡迎第一次訪問(wèn)"); }});12345678910111234567891011

session

什么是session?

session是另一種記錄客戶狀態(tài)的機(jī)制,不同的是Cookie保存在客戶端瀏覽器中,而session保存在服務(wù)器上。

客戶端瀏覽器訪問(wèn)服務(wù)器的時(shí)候,服務(wù)器把客戶端信息以某種形式記錄在服務(wù)器上,這就是session。客戶端瀏覽器再次訪問(wèn)時(shí)只需要從該Session中查找該客戶的狀態(tài)就可以了。

如果說(shuō)Cookie機(jī)制是通過(guò)檢查客戶身上的“通行證”來(lái)確定客戶身份的話,那么session機(jī)制就是通過(guò)檢查服務(wù)器上的“客戶明細(xì)表”來(lái)確認(rèn)客戶身份。

session相當(dāng)于程序在服務(wù)器上建立的一份客戶檔案,客戶來(lái)訪的時(shí)候只需要查詢客戶檔案表就可以了。

兩者的區(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。

所以建議:將登陸信息等重要信息存放為session、其他信息如果需要保留,可以放在cookie中

express中的session

跟cookie一樣都需要單獨(dú)的安裝和引用模塊, 安裝模塊:

$npm install express-session11

這個(gè)模塊沒(méi)有默認(rèn)安裝,需要自己手動(dòng)安裝,并引入: var session = require('express-session');

這個(gè)模塊的主要的方法是 session(options),其中 options 中包含可選參數(shù),主要有:

name: 設(shè)置 cookie 中,保存 session 的字段名稱,默認(rèn)為 connect.sid 。store: session 的存儲(chǔ)方式,默認(rèn)存放在內(nèi)存中,也可以使用 redis,mongodb 等。express 生態(tài)中都有相應(yīng)模塊的支持。secret: 通過(guò)設(shè)置的 secret 字符串,來(lái)計(jì)算 hash 值并放在 cookie 中,使產(chǎn)生的 signedCookie防篡改。cookie: 設(shè)置存放 session id 的 cookie 的相關(guān)選項(xiàng),默認(rèn)為 (default: { path: ‘/’,httpOnly: true, secure: false, maxAge: null })genid: 產(chǎn)生一個(gè)新的 session_id 時(shí),所使用的函數(shù), 默認(rèn)使用 uid2 這個(gè) npm 包。rolling: 每個(gè)請(qǐng)求都重新設(shè)置一個(gè) cookie,默認(rèn)為 false。resave: 即使 session 沒(méi)有被修改,也保存 session 值,默認(rèn)為 true。

使用方法:

app.use(session({ secret: 'hubwiz app', //secret的值建議使用隨機(jī)字符串 cookie: {maxAge: 60 * 1000 * 30} // 過(guò)期時(shí)間(毫秒)}));app.get('/session', function (req, res) { if (req.session.sign) {//檢查用戶是否已經(jīng)登錄 console.log(req.session);//打印session的值 res.send('welecome <strong>' + req.session.name + '</strong>, 歡迎你再次登錄'); } else { req.session.sign = true; req.session.name = 'https://github.com/CleverFan'; res.send('歡迎登陸!'); }});12345678910111213141234567891011121314

session的持久化

重新運(yùn)行npm start,然后刷新訪問(wèn)測(cè)試頁(yè)面。我們會(huì)發(fā)現(xiàn)session丟了! 這是因?yàn)閟ession會(huì)默認(rèn)的存儲(chǔ)到內(nèi)存當(dāng)中。也就是說(shuō)session數(shù)據(jù)都是存儲(chǔ)在內(nèi)存當(dāng)中的,當(dāng)進(jìn)程退出后,session數(shù)據(jù)就會(huì)丟失。

在開(kāi)發(fā)環(huán)境中,這也許并不算什么壞事。但是如果線上的應(yīng)用是這樣的,用戶絕對(duì)是不能忍受的。所以,我們需要將session數(shù)據(jù) 持久化存儲(chǔ)。

首先我們講解如何把session存儲(chǔ)到mongodb數(shù)據(jù)庫(kù)當(dāng)中:

在使用MongoDB存儲(chǔ)時(shí)首先要加載一個(gè)模塊:connect-mongo以及mongoose

安裝命令: npm install connect-mongo npm install mongoose

var mongoose = require("mongoose");var session = require('express-session');var MongoStore = require('connect-mongo/es5')(session);mongoose.connect('mongodb://127.0.0.1:27017/sessiontest'); //連接數(shù)據(jù)庫(kù)mongoose.connection.on('open', function () { console.log('-----------數(shù)據(jù)庫(kù)連接成功!------------');});app.use(session({ secret: "what do you want to do?", //secret的值建議使用隨機(jī)字符串 cookie: {maxAge: 60 * 1000 * 60 * 24 * 14}, //過(guò)期時(shí)間 resave: true, // 即使 session 沒(méi)有被修改,也保存 session 值,默認(rèn)為 true saveUninitialized: true, store: new MongoStore({ mongooseConnection: mongoose.connection //使用已有的數(shù)據(jù)庫(kù)連接 })}));123456789101112131415161718123456789101112131415161718mongodb我就不講了,不是本文重點(diǎn),需要?jiǎng)?chuàng)建sessiontest數(shù)據(jù)庫(kù)。11

Redis是一個(gè)非常適合用于Session管理的數(shù)據(jù)庫(kù)。

它的結(jié)構(gòu)簡(jiǎn)單,key-value的形式非常符合SessionID-UserID的存儲(chǔ);讀寫速度非???;自身支持?jǐn)?shù)據(jù)自動(dòng)過(guò)期和清除;語(yǔ)法、部署非常簡(jiǎn)單。

基于以上原因,很多Session管理都是基于Redis實(shí)現(xiàn)的。所以我們這個(gè)示例將用redis管理session。

Express已經(jīng)將Session管理的整個(gè)實(shí)現(xiàn)過(guò)程簡(jiǎn)化到僅僅幾行代碼的配置的地步了,你完全不用理解整個(gè)session產(chǎn)生、存儲(chǔ)、返回、過(guò)期、再頒發(fā)的結(jié)構(gòu),使用Express和Redis實(shí)現(xiàn)Session管理,只要兩個(gè)中間件就足夠了:

express-sessionconnect-redis

參數(shù)

client 你可以復(fù)用現(xiàn)有的redis客戶端對(duì)象, 由 redis.createClient() 創(chuàng)建host Redis服務(wù)器名port Redis服務(wù)器端口socket Redis服務(wù)器的unix_socket

可選參數(shù)

ttl Redis session TTL 過(guò)期時(shí)間 (秒)disableTTL 禁用設(shè)置的 TTLdb 使用第幾個(gè)數(shù)據(jù)庫(kù)pass Redis數(shù)據(jù)庫(kù)的密碼prefix 數(shù)據(jù)表前輟即schema, 默認(rèn)為 “sess:”

如何使用:

var express = require('express');var session = require('express-session');var RedisStore = require('connect-redis')(session);var app = express();var options = { "host": "127.0.0.1", "port": "6379", "ttl": 60 * 60 * 24 * 30, //session的有效期為30天(秒)};// 此時(shí)req對(duì)象還沒(méi)有session這個(gè)屬性app.use(session({ store: new RedisStore(options), secret: 'express is powerful'}));1234567891011121314151612345678910111213141516

沒(méi)有實(shí)際應(yīng)用的博客不是好博客

最后,用一個(gè)簡(jiǎn)單的登錄驗(yàn)證小項(xiàng)目結(jié)束本篇文章。

index.ejs:

<form action="/sign" method="post"> <fieldset> <legend>Please sign in</legend> <p>User: <input type="text" name="user"/></p> <p>Pass: <input type="text" name="passWord"/></p> <button>Submit</button> </fieldset></form>123456789123456789

sign.ejs

<!doctype html><html><head> <title>session</title></head><body> <!--登錄成功展示的內(nèi)容--> <p>welecome <strong> <%=session.name%> </strong>, 歡迎你再次登錄<a href="/out"></a></p></body></html>1234567891012345678910

user.json

{ "admin":{ "password": "admin", "name": "demo" }}123456123456

admin為登錄用戶名,password為登錄密碼,name為用戶昵稱。

app.js

var express = require('express');var path = require('path');var favicon = require('serve-favicon');var logger = require('morgan');var cookieParser = require('cookie-parser');var bodyParser = require('body-parser');var session = require('express-session');var routes = require('./routes/index');var user = require('./user.json');var app = express();// view engine setupapp.set('views', path.join(__dirname, 'views'));app.set('view engine', 'ejs');// uncomment after placing your favicon in /public//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));app.use(logger('dev'));app.use(bodyParser.json());app.use(bodyParser.urlencoded({ extended: false }));app.use(cookieParser());app.use(express.static(path.join(__dirname, 'public')));// app.use('/', routes);// app.use('/users', users);app.use(session({ secret: 'secret', //為了安全性的考慮設(shè)置secret屬性 cookie: {maxAge: 60 * 1000 * 30}, //設(shè)置過(guò)期時(shí)間 resave: true, // 即使 session 沒(méi)有被修改,也保存 session 值,默認(rèn)為 true saveUninitialized: false, //}));app.get('/', function (req, res) { if (req.session.sign) {//檢查用戶是否已經(jīng)登錄,如果已登錄展現(xiàn)的頁(yè)面 console.log(req.session);//打印session的值 res.render('sign.ejs', {session:req.session}); } else {//否則展示index頁(yè)面 res.render('index.ejs', {title: 'index'}); }});//登錄表單處理app.post('/sign', function (req, res) { //登錄的數(shù)據(jù)和user.json中的數(shù)據(jù)進(jìn)行對(duì)比 if(!user[req.body.user]){ res.end("input wrong"); } if (req.body.password != user[req.body.user].password || !user[req.body.user]) { res.end('sign failure'); } else { req.session.sign = true; req.session.name = user[req.body.user].name; res.send('welecome <strong>' + req.session.name + '</strong>,<a href="/out">登出</a>'); }});app.get('/out', function(req, res){ req.session.destroy(); res.redirect('/');});// catch 404 and forward to error handlerapp.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err);});// error handlers// development error handler// will print stacktraceif (app.get('env') === 'development') { app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: err }); });}// production error handler// no stacktraces leaked to userapp.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: {} });});module.exports = app;12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697981234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798

現(xiàn)在啟動(dòng)項(xiàng)目,就可以使用這個(gè)demo了。

項(xiàng)目源代碼我會(huì)放在github上,感興趣的可以去下載。 github地址:https://github.com/CleverFan/nodejsStudy/tree/master/expressTest/day02_session

歡迎大家和我討論,畢竟我也是個(gè)萌新-.-


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 毛片在线免费视频 | 国产视频在线免费观看 | 国产成人精品一区二区三区电影 | 在线a毛片免费视频观看 | 亚洲人片在线观看 | 成人午夜一区二区 | 久久草在线视频国产 | 激情网站视频 | 日韩黄色片免费看 | 久久精品视频69 | 一区二区三区无码高清视频 | 一区二区三区日韩在线观看 | 免费观看国产精品视频 | 欧美色另类 | 中文字幕一二区 | 欧美日韩视频第一页 | 暴力强行进如hdxxx | 91 视频网站| 中文字幕在线亚洲精品 | 中文字幕偷拍 | 99re久久最新地址获取 | 失禁高潮抽搐喷水h | 国产88久久久国产精品免费二区 | 青青草成人影视 | 黄在线观看 | 欧美一极视频 | 久久国产成人精品国产成人亚洲 | 羞羞视频免费视频欧美 | 国产精品久久久久久久四虎电影 | 深夜毛片免费看 | 中文字幕精品一二三四五六七八 | 免费一级特黄做受大片 | 国产一级免费在线视频 | 免费国产不卡午夜福在线 | 国产一区二区三区视频在线 | 55夜色66夜色国产精品视频 | 午夜视频在线免费观看 | 欧美一级做性受免费大片免费 | 成人午夜免费看 | 日本黄色一级电影 | 美国一级黄色毛片 |