nodejs使用express,crypto配合validator实现用户登录逻辑
nodejs使用express,crypto配合validator实现用户登录逻辑
piggybear 发表于3年前
nodejs使用express,crypto配合validator实现用户登录逻辑
  • 发表于 3年前
  • 阅读 13
  • 收藏 0
  • 点赞 0
  • 评论 0

新睿云服务器60天免费使用,快来体验!>>>   

最近的项目使用express来写,这也是我尝试写的第一个nodejs的大型项目。今天实现了半天的登陆逻辑,还是很费劲的,在此记录一下。

大部分的知识都是从https://github.com/cnodejs/nodeclub 这份源码学到的,还有express官方的一个登陆验证示例

https://github.com/visionmedia/express/blob/master/examples/auth/app.js

当然还有api  http://expressjs.jser.us/api.html#res.status  但是吐槽一下,express的api。。真心崎岖。。

首先最坑的一点。。。让session生效

 app.use(express.cookieParser());//开启cookie app.use(express.session({//开启session secret: config.session_secret })); app.use(app.router);

那么注意了,前两行一定要写在app.router这个中间件前面!否则session始终未定义!

之后我们开始书写session与cookie配合的逻辑。

基本逻辑:

  • 进入网站后(此时没有session),从cookie中取加密的数据,进行验证,若验证成功,在session中存储user,用户免登陆。
  • 进入首页时(需要登录的页面),若session中没有user,则自动跳到登陆页面。
  • 登陆时,采用post方式提交用户信息,利用加密算法进行加密,存储登录信息到cookie中。
  • 数据库采用的mysql,采用啥都无所谓。。因为我是通过http与后端写好的统一登陆接口进行通信的。登陆成功返回0,失败返回-9999

ok,下面来一条条的实现这些逻辑。

首先我们利用crypto这个牛逼的加密加密库进行加密解密操作

var crypto = require('crypto'); //加密 function encrypt(str, secret) { var cipher = crypto.createCipher('aes192', secret); var enc = cipher.update(str, 'utf8', 'hex'); enc += cipher.final('hex'); return enc; } //解密 function decrypt(str, secret) { var decipher = crypto.createDecipher('aes192', secret); var dec = decipher.update(str, 'hex', 'utf8'); dec += decipher.final('utf8'); return dec; }

他的作用主要是把用户名密码进行加密存到cookie,读取时解密。而密文我们在配置文件中配置即可。

第一个逻辑需要一个加密与解密的操作。而进入网站开始就进行操作的话,可以使用app.use中间件。

 app.use(express.cookieParser());//开启cookie app.use(express.session({//开启session secret: config.session_secret })); app.use(require('./controller/site').auth_user); // 添加这个中间件,用来解析cookie app.use(app.router);

然后controller/side中auth_user如下

exports.auth_user = function (req, res, next) { if (req.session.user) { return next();//若没有session,直接跳过此中间件 } else { var cookie = req.cookies[config.auth_cookie_name];//读cookie,通过配置文件中标识符读cookie if (!cookie) { return next();//若没有此站点的cookie,直接跳过此中间件 } var auth_token = decrypt(cookie, config.session_secret);//解密操作 var auth = auth_token.split('\t'); var user = auth[0], passwd = auth[1];//解密后拿到username与password var data = { parament:user, password:passwd, route:'checkLogin', } var userLoginConf = config.apiService.userLogin; postData.send(data, userLoginConf, function (result) {//这部分为post的api请求进行验证。 if (result == 0) { req.session.user = user.username;//存在此用户,开启session,存储user return next();//进行下一步 } else {//不存在此用户,进行下一步 return next(); } }) } };

第二个逻辑很简单。我们直接使用一个私有函数即可。

/*session无效验证*/ function noSession(req,res){ if (!req.session || !req.session.user) { res.redirect('login'); return; } }

第三个逻辑,配合router进行表单提交的工作

router:

 app.post('/login', site.login);

controller:

exports.login = function (req, res) { /*处理空值与注入*/ var param = handleParam(req.body) var data ={ parament : param.username, password: param.password, route: 'checkLogin', } var userLoginConf = config.apiService.userLogin; postData.send(data,userLoginConf,function(result){//与后端api接口通信 if(result ==0){//登陆成功 var user = { 'username':data.parament, 'password':data.password } gen_session(user, res);//生成cookie /*这个逻辑暂时没开,这是为了做那种“返回刚才页面”的需求 //check at some page just jump to home page var refer = req.session._loginReferer || 'home'; for (var i = 0, len = notJump.length; i !== len; ++i) { if (refer.indexOf(notJump[i]) >= 0) { refer = 'home'; break; } } res.redirect(refer); */ req.session.regenerate(function(){//写session。存入username // Store the user's primary key // in the session store to be retrieved, // or in this case the entire user object req.session.user = user.username; res.render('home',[]);//渲染数据,随便怎么渲染了。。 }); }else{ res.render('login',[]);//登录失败,跳转到login。这里我没有加提示信息。 } }) };

 这里处理注入使用了validator模块

var check = require('validator').check, sanitize = require('validator').sanitize; /*处理空值与注入*/ function handleParam(params){ var params = params || {}; var safeParam = {}; for(var key in params){ var trimed = sanitize(params[key]).xss(); var blockXssed = sanitize(trimed).xss(); safeParam[key] = blockXssed } return safeParam }

当然最后我们也要有个登出逻辑了

exports.logout = function (req, res, next) {//代码很简单,就不解释了 req.session.destroy(); res.clearCookie(config.auth_cookie_name, { path: '/' }); res.redirect(req.headers.referer || 'login'); };

最后感谢写nodeclub  https://github.com/cnodejs/nodeclub 的各位,在你们的源码里学到了很多很多的东西!

  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 3
博文 237
码字总数 37552
×
piggybear
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: