实现会话验证
1 var express=require('express'); 2 var bodyParser=require('body-parser'); 3 var cookieParser=require('cookie-parser'); 4 var session=require('express-session'); 5 var crypto=require('crypto'); 6 // 生成安全密码 7 function hashPW(pwd){ 8 return crypto.createHash('sha256').update(pwd). 9 digest('base64').toString(); 10 } 11 var app=express(); 12 // app.use(bodyParser()); 13 app.use(bodyParser.urlencoded({ 14 extended: true 15 })); 16 app.use(bodyParser.json()); 17 app.use(cookieParser('MAGICString')); 18 // app.use(session()); 19 app.use(session({ 20 secret: 'weizai', 21 resave: true, 22 saveUninitialized: true 23 })); 24 app.get('/restricted',function(req,res){ 25 if(req.session.user){ 26 res.send('<h2>'+req.session.success+'</h2>'+ 27 '<p>You have entered the restricted section</p><br>'+ 28 '<a href="/logout">logout</a>' 29 ); 30 }else{ 31 req.session.error='Access denied'; 32 res.redirect('/login'); 33 } 34 }); 35 app.get('/logout',function(req,res){ 36 req.session.destroy(function(){ 37 res.redirect('/login'); 38 }) 39 }) 40 app.get('/login',function(req,res){ 41 var response='<form method="POST">'+ 42 '<input type="text" name="username"><br>'+ 43 '<input type="password" name="password"><br>'+ 44 '<input type="submit" value="Submit"></form>'; 45 if(req.session.user){ 46 res.redirect('/restricted'); 47 }else if(req.session.error){ 48 response+='<h2>'+req.session.error+'</h2>'; 49 } 50 res.type('html'); 51 res.send(response); 52 }) 53 app.post('/login',function(req,res){ 54 // var user={name:req.body.username,password:hashPW("myPass")}; 55 var user={name:'weizai',password:hashPW("myPass")}; 56 if(user.password==hashPW(req.body.password.toString())){ 57 // 移除并创建新的req.session()会话 58 req.session.regenerate(function(){ 59 req.session.user=user; 60 req.session.seccess='Authenticated as '+user.name; 61 res.redirect('/restricted'); 62 }) 63 }else{ 64 req.session.regenerate(function(){ 65 req.session.error='Authentication failed'; 66 res.redirect('/restricted'); 67 }); 68 // res.redirect('/login'); 69 } 70 }); 71 app.listen(8081);
1.使用crypto模块生成安全的密码实现会话验证
1.利用hashPW()函数对密码加密,使用body-parser,cookieParser和session中间件
55行 模拟数据库得到一个user对象并把储存的密码散列值与请求正文中的密码散列值比较
58-61行 创建会话。regenerate()函数用来重新生成一个新的会话,传给regenerate()的回调函数设置会话的session.user和session.success属性。
验证失败,只会为会话session.error属性
40-51行 /login路由显示一个基本的登录获取证书。若session.error被设置,它也会显示在登录页面上。
24-33行 /restricted路由检查会话,看是否是有效的用户。是的话显示成功信息,否则session.error被设置,响应被重新定向到/login
35-38行 /logout路由在会话上调用destroy()方法删除身份验证。
方法 | 说明 |
regenerate([callback]) | 移除并创建一个词新的req.session对象,让你重置会话 |
destroy([callback]) | 移除req.session对象 |
save([callback]) | 保存会话数据 |
touch([callback]) | 为会话重置maxAge计数 |
cookie | 指定把绘画链接到浏览器的cookie对象 |