nodejs使用express,crypto配合validator实现用户登录逻辑
来源:互联网 发布:淘宝商城招商 编辑:程序博客网 时间:2024/06/03 12:27
最近的项目使用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 的各位,在你们的源码里学到了很多很多的东西!
- nodejs使用express,crypto配合validator实现用户登录逻辑
- Express+Nodejs 下的登录拦截实现
- 使用nodejs、mongodb、express、linux搭建社区网站(5)-用户登录及个人主页
- nodejs Crypto使用
- nodejs + mongodb 实现用户登录
- NodeJS Express 视图查找逻辑
- nodejs + mongodb 实现用户登录的资源
- nodejs实战express笔记之实现用户和文章页面
- 基于nodejs使用session控制用户登录
- nodejs express 做登录拦截
- nodejs express 框架使用
- 使用nodejs+express开发
- nodejs-express使用
- jsp配合java文件实现用户登录程序
- express使用session实现登录身份认证
- NodeJS-crypto
- Node.js+Express+MySql实现用户登录注册
- express-validator
- HDU 1524 A Chess Game 【SG函数】
- 对类的理解
- 发来的卡夫卡法规和共和国
- 使用CStdioFile 读写UNICODE文档
- 今天第一次写博客,先不说技术了
- nodejs使用express,crypto配合validator实现用户登录逻辑
- c# ThreadPool 应用实例
- 2014华为机试-在字符串中找出连续最长的数字串
- 命名空间
- Split a string using String.split()Tag(s): String/Number
- http://blog.csdn.net/xiaanming/article/details/9401981
- linux 同步时间
- c++ 求解数列最大的两个子段和
- leetcode Interleaving String