zoukankan      html  css  js  c++  java
  • 单点登录

    转载单点登录

    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,注意依赖包

  • 相关阅读:
    bzoj5253 [2018多省省队联测]制胡窜
    bzoj5249 [2018多省省队联测]IIIDX
    bzoj5248 [2018多省省队联测]一双木棋
    HEOI2018 游记
    bzoj2720 [Violet 5]列队春游
    bzoj4871 [Heoi2017]摧毁“树状图”
    bzoj3991 [SDOI2015]寻宝游戏
    bzoj3598 [Scoi2014]方伯伯的商场之旅
    Flash平台的分析与RIA的趋势
    JavaScript的变量预解析特性
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/4449293.html
Copyright © 2011-2022 走看看