Express实现Session+Cookie认证

来源:互联网 发布:windows 10界面 编辑:程序博客网 时间:2024/04/27 20:05

Express

Express 并非真正的 MVC
它是工作流的思想:

水->净化->调配->装瓶->质检->饮用可乐

var express=require('express');var app=express();app.get('/',function(req,res){    res.send('Hello World');});var server=app.listen(3000,function(){    var host=server.address().address;    var port=server.address().port;    console.log("examle app listening at http://%s :%s",host,port);});

这里创建了一个最简单的Express服务器, 但是我们的实际项目比这个复杂得多。

利用Express 托管静态文件

通过Express内置的express.static 可以方便地托管静态文件,如图片、CSS、JavaScript文件等。
将静态资源文件所在目录作为参数传递给express.static 中间件就可以提供静态资源文件的访问了。

//设置public文件夹为存放静态文件的目录app.use(express.static(path.join(__dirname, 'public')));//express.static added by Jason 同时挂载路径app.use('/static',express.static('public'));

Express中间件

Express是一个自身功能,极简,完全由路由和中间件构成一个web开发框架: 本质来说,一个Express应用就是在调用各种中间件!

Middleware : 是一个函数,它可以访问request object 和 response object! 可以访问 next() 这也是一个中间件,用于处理请求响应循环流程中的中间件。
功能: 执行任何代码,
修改请求和响应对象,
终结请求和响应循环。
调用堆栈中的下一个中间件。
注意
如果没有 终结请求-响应循环, 就必须调用next()方法将控制权交给下一个中间件,否则请求会挂起。

在app.js使用Cookie和Session中间件

//加载解析cookie的middlewareapp.use(cookieParser());// //using session set sessionapp.use(session({  secret:'face', //used to sign the sessionid cookie  store:new mongoStore({    url:dbUrl,    collection:'sessions'  }),  name:'faceUser', //cookie name i set,every time request will send  cookie:{maxAge:1000*60*60*24},//1day  resave:false,  saveUninitialized:false}));

解释
首先我们挂载了cookieParser解析中间件,然后我们使用session中间件,并配置它,配置主要是cookie的名字,cookie过期时间、它的store参数则是一个MongoStore实例,把会话信息存到MongoDB数据库中~ 防止丢失!

重点

app.use表示挂载这个中间件,默认挂载到 “/”路径,如果指定了路径就挂载到指定路径
挂载到路径上面之后,这个中间件函数就会在每次请求路径匹配到这个path的时候被执行!
如果你没有指定path路径,那么默认来说,每次请求都会被执行!
中间件是顺序执行的,跟队列很像
一般来说就是通过next()触发,流程如下

这里写图片描述

中间件原理

中间件和filter的工作原理类似,进入具体业务之前,先让过滤器处理。 中间件就是HTTP请求到具体业务逻辑之间处理那些细节的功能函数。 一般采用尾触发也就是next()

比如上面的cookieParser可能是这样的:

var cookie=function(req,res,next){    var cookie=req.header.cookie;    var cookies={};    if(cookie){        var list=cookie.split(";");        for(var i=0;i<list.length;i++){            var pair=list[i].split('=');            cookies[pair[0].trim()]=pair[1];        }    }    req.cookies=cookies;    next();//尾触发}

对于app.use()

实质实现是这样:

app.use=function(path){    var handle;    if(typeof path==='string'){        //第一个参数作为路径        path:pathRegexp(path),        //其他都是处理单元        stack:Array.prototype.slice.call(arguments,1);    }else{        handle={            path:pathRegexp('/'),            stack:Array.prototype.slice.call(argumemts,0)        };    }    route.all.push(handle);}

将handle这个对象压入route.all,handle中包含了处理函数名和路径信息。

真实的匹配应该是这样的

var match=function(pathname,routes){    var stacks=[];    for(var i=0;i<routes.length;i++){        var route=routes[i];        //正则匹配        var reg=route.path.regexp;        var matched=reg.exec(pathname);        if(matched){        //抽取具体值        //将中间件保存起来        stacks=stacks.concat(route.stack);        }    }    return stacks;}

这是个匹配,为了将我们压入到routes中的handle对象按照匹配的路径抽取出来。 然后连接成一个stack数组返回。

function (req,res){    var pathname=url.parse(req.url).pathname;    //将请求方法变为小写    var method=req.method.toLowerCase();    //获取all方法里面的中间件    var stacks=match(pathname,routes.all);    if(routes.hasOwnProperty(method)){        //根据请求方法分发,获取相关中间件        stacks.concat(match(pathname,routes[method]));    }    if(stack.length){        handle(req,res,stacks);    }else{        //404    }}

在这里我们将获取匹配的中间件,存到stacks数组中,然后将这些方法传递给handle()函数执行,handle就是提取这个数组的方法然后一个一个执行。 handle这里就不讲了,还涉及到异常捕获。

0 0