标签:
oken; 24 //如果url带有token,则表明已经在passport鉴权过 25 if (token) { 26 //存在token,则在内存中寻找之前与用户的映射关系 27 //异步的 28 fs.readFile(token_path, ‘utf8‘, function (err, data) { 29 if (err) throw err; 30 if (!data) data = ‘{}‘; 31 data = JSON.parse(data); 32 //如果存在标志,则验证通过 33 if (data[token]) { 34 res.redirect(‘http://‘ + from + ‘?token=‘ + token); 35 return; 36 } 37 //如果不存在便引导至登录页重新登录 38 res.redirect(‘/‘); 39 }); 40 } else { 41 res.render(‘index‘, { 42 title: ‘统一登录passport‘ 43 }); 44 } 45 }); 46 47 router.post(‘/‘, function (req, res, next) { 48 if (!req.query.from) return; 49 var name = req.body.name; 50 var pwd = req.body.password; 51 var from = req.query.from; 52 var token = new Date().getTime() + ‘_‘; 53 var cookieObj = {}; 54 var token_path = path.resolve() + ‘/token_user.json‘; 55 //简单验证 56 if (name === pwd) { 57 req.flash(‘success‘, ‘登录成功‘); 58 //passport生成用户凭证,并且生成令牌入cookie返回给子系统 59 token = token + name; 60 res.setHeader("Set-Cookie", [‘token=‘ + token]); 61 //持久化,将token与用户的映射写入文件 62 fs.readFile(token_path, ‘utf8‘, function (err, data) { 63 if (err) throw err; 64 if (!data) data = ‘{}‘; 65 data = JSON.parse(data); 66 //以token为key 67 data[token] = name; 68 //存回去 69 fs.writeFile(token_path, JSON.stringify(data), function (err) { 70 if (err) throw err; 71 }); 72 }); 73 res.redirect(‘http://‘ + from + ‘?token=‘ + token); 74 } else { 75 console.log(‘登录失败‘); 76 } 77 }); 78 module.exports = router;
子系统A的实现
1 var express = require(‘express‘); 2 var router = express.Router(); 3 var request = require(‘request‘); 4 5 /* GET home page. */ 6 router.get(‘/‘, function (req, res, next) { 7 var token = req.query.token; 8 var userid = null; 9 //如果本站已经存在凭证,便不需要去passport鉴权 10 if (req.session.user) { 11 res.render(‘index‘, { 12 title: ‘子产品-A-‘ + req.session.user, 13 user: req.session.user 14 }); 15 return; 16 } 17 //如果没有本站信息,又没有token,便去passport登录鉴权 18 if (!token) { 19 res.redirect(‘http://passport.com?from=a.com‘); 20 return; 21 } 22 //存在token的情况下,去passport主站检查该token对应用户是否存在, 23 //存在并返回对应userid 24 //这段代码是大坑!!!设置的代理request不起效,调了3小时 25 request( 26 ‘http://127.0.0.1:3000/check_token?token=‘ + token + ‘&t=‘ + new Date().getTime(), 27 function (error, response, data) { 28 if (!error && response.statusCode == 200) { 29 data = JSON.parse(data); 30 if (data.code == 0) { 31 //这里userid需要通过一种算法由passport获取, 32 //这里图方便直接操作token 33 //因为token很容易伪造,所以需要去主战验证token的有效性, 34 //一般通过webservers 这里验证就简单验证即可...... 35 userid = data.userid; 36 //有问题就继续登录 37 if (!userid) { 38 res.redirect(‘http://passport.com?from=a.com‘); 39 return; 40 } 41 //取得userid后,系统便认为有权限去数据库根据用户id获取用户信息 42 //根据userid操作数据库流程省略...... 43 // req.session.user = userid; 44 res.render(‘index‘, { 45 title: ‘子产品-A-‘ + userid, 46 user: userid 47 }); 48 return; 49 } else { 50 //验证失败,跳转 51 res.redirect(‘http://passport.com?from=a.com‘); 52 } 53 } else { 54 res.redirect(‘http://passport.com?from=a.com‘); 55 return; 56 } 57 }); 58 }); 59 module.exports = router;
passport鉴权程序模拟
1 var express = require(‘express‘); 2 var router = express.Router(); 3 var path = require(‘path‘); 4 var fs = require(‘fs‘); 5 6 /* GET users listing. */ 7 router.get(‘/‘, function(req, res, next) { 8 var token = req.query.token; 9 var ret = {}; 10 var token_path = path.resolve() + ‘/token_user.json‘; 11 ret.code = 1;//登录失败 12 if(!token) { 13 res.json(ret); 14 return; 15 } 16 //如果传递的token与cookie不等也认为是鉴权失败 17 // if(token != cookieObj[‘token‘]){ 18 // res.json(ret); 19 // return; 20 // } 21 fs.readFile(token_path, ‘utf8‘, function (err, data) { 22 if (err) throw err; 23 if(!data) data = ‘{}‘; 24 data = JSON.parse(data); 25 //如果存在标志,则验证通过,未考虑账号为0的情况 26 if(data[token]) { 27 ret.code = 0;//登录成功 28 ret.userid = data[token]; 29 } 30 res.json(ret); 31 }); 32 }); 33 module.exports = router;
测试之前需要设置host,这里继续采用fiddler神器帮助:
这边直接用node跑了3个服务器:
然后打开浏览器输入a.com,直接跳到了,登录页:
简单登录后(账号密码输入一致即可):
这个时候直接进入子系统B:
直接便登录了,说明方案大体上是可行的
首先,这里的程序很简陋,很多问题,也没有做统一退出的处理,今天主要目的是了解单点登录,后面有实际工作再求深入。
这里附上源码,感兴趣的朋友看看吧:http://files.cnblogs.com/files/yexiaochai/web.rar,注意依赖包
标签:
原文地址:http://www.cnblogs.com/Leo_wl/p/4449293.html