nodejs实现登录注册系统

来源:互联网 发布:淘宝朵以专卖店 编辑:程序博客网 时间:2024/05/16 19:08

nodejs实现登录注册系统

对上一次的功能进一步的完善,将用户的数据储存在本地数据库,实现登录的功能,采用session机制记录登录信息,使得已登录的用户保持登录状态


目录结构

目录结构比较简单,算是一个小的demo

这里写图片描述

  • model是数据层,将采用mongoose创建数据库模型,并提供接口
  • public是静态资源,随http发送请求并加载
  • routes是控制层,包含路由控制和逻辑处理
  • views是视图层,主要有三个页面
  • signin是入口文件

数据处理

Mongoose是一个提供了MongoDB地相映射的Node.js库,创建一个数据库模型schema,并将其发布成为model,统一数据模型并能进行操作

var mongoose = require("mongoose");mongoose.connect('mongodb://localhost/test');var Schema = mongoose.Schema;//骨架模版var userSchema = new Schema({    username   : String,    password   : String,    id    : String,    phone : String,    email  : String})var User = mongoose.model('User', userSchema);module.exports = User;

路由控制

主要是由routes.js控制,注意要加载静态资源和对session的设置,注册中间件

var express = require('express')var routes = require('./server')var app = express();var bodyParser = require('body-parser');var session = require('express-session')// 创建 application/x-www-form-urlencoded 编码解析var urlencodedParser = bodyParser.urlencoded({ extended: false })module.exports = function(app) {    // 设置页面的跳转还有session的设置    app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }}))    app.use('/',routes);    app.use('/regist',routes);    app.use('/logout',routes);    app.use('/info',routes);    app.use('/check', routes);    app.use(express.static(__dirname + '/public'));}

逻辑处理

路由的控制还是在server.js中对逻辑的处理,并选择渲染的页面

  • 通过引入express.Router(),对其中的具体方法和回调函数进行处理
  • 视图层的显示采用动态模板进行渲染,因此render进行页面渲染的时候也提供了必要的数据
  • 对于用户登录的和退出时通过请求req.session对登录状态进行标示
  • 处于安全性考虑,数据库直接存放用户的密码,进行加密后判断
router.get('/regist',function (req, res) {    res.render('index.ejs', {        errorInfo:'请输入信息'    })})router.get('/',function(req, res) {// 默认登录到index要判断扥估状态,已经登录的用户进入详情页面    if (!req.session.logged_in) {        Notlogin(req, res)    } else {        loggedIn(req, res)    }})//退出登录的用户进入登录页面router.get('/logout', function(req, res) {    req.session.logged_in = 0;    res.render('signin.ejs', {        errorInfo:'请输入信息'    })})//登录处理router.post('/check', urlencodedParser, function (req, res) {    console.log("check password");    var testuser = {        username:req.body.username,        password:req.body.password,    }    //这里采用md5对密码进行加密后在储存到数据库当中    var d = getMD5Password(testuser.password)    console.log("加密的结果:(验证)"+d);    testuser.password = d;    //采用model的方法,已经提供了各种接口,查找数据库中是否有次用户的信息,对用户登录进行验证    User.find(testuser, function (err, detail) {        if (detail.length) {            signinCheckSuccess(detail, req, res)        } else {            console.log("wrong!");            errorInfo = "用户名不存在或密码错误";            res.render('signin.ejs',{                errorInfo:errorInfo            })        }    })})//注册处理router.post('/info', urlencodedParser, function(req, res) {    console.log("Data from submit form");    var user = new User({        username:req.body.username,        password:req.body.password,        id:req.body.id,        phone:req.body.phone,        email:req.body.email    })    var d = getMD5Password(user.password);    console.log("加密的结果:"+d);    user.password = d;    console.log(user);    var flag = {one:1,two:1,three:1,four:1};    errorInfo = "";    //这里对数据进行验证,不能够有重复的数据    checkDataRep(user, flag, req, res);})

其他工具函数

主要针对是否有用户登录之后的一些逻辑的判断,以及对数据库查找的格式进行统一,处理回调函数

// 验证用户注册提交的表单,如果没有问题,则记录登录状态function dealWithDataSubmited (user, flag, req, res) {    if (!(flag.one&&flag.two&&flag.three&&flag.four)) {        repreload(res);    } else {        req.session.username = user.username;        req.session.logged_in = 1;        user.save(function(err) {            if (err) {                console.log('保存失败');                return;            }            console.log('保存成功');        })        console.log(user.username + " has been added");        showInfo(user, res)    }}// user的find方法采用json格式,因此将传进去的名字转化为json格式之后对数据库进行访问,并处理逻辑,渲染页面function findJson(name, res) {    var testUsername = {username:name};    User.find(testUsername,function (err, userDetail) {        if (userDetail.length == 0) {            console.log(userDetail);            res.render('index.ejs', {                errorInfo:'请输入信息'            });        } else {            console.log(userDetail);            console.log("Load user: " + name);            console.log(userDetail[0]);            showInfo(userDetail[0], res);        }    })}// 对用户访问index页面的逻辑进行处理,主要是看url后面有没有附带信息function Notlogin(req, res) {    if (req.param("username") == undefined) {        console.log("initial page");        res.render('signin.ejs', {            errorInfo:'请输入信息'        })    } else {        var username = req.param("username").toString();        console.log("find user: " +  username);        findJson(username, res)    }}// 如果已经有用户登录了就显示当前登录的用户function loggedIn(req, res) {    if (req.param("username") == undefined) {        findJson(req.session.username, res);    } else {        var username = req.param("username").toString();        console.log(username);        // 不能显示非当前登录用户的信息        if (username != req.session.username) {            var testUsername = {username:req.session.username};            User.find(testUsername,function (err, userDetail) {                infoPage(res, userDetail, "只能显示已登录用户")            })        } else {            var testUsername = {username:req.session.username};            User.find(testUsername,function (err, userDetail) {                infoPage(res, userDetail, "用户详情")            })        }    }}function getMD5Password(content) {    var md5 = crypto.createHash('md5');//定义加密方式:md5不可逆,此处的md5可以换成任意hash加密的方法名称;    md5.update(content);    var d = md5.digest('hex');  //加密后的值d    return d;}// 处理数据,注意格式function signinCheckSuccess(detail, req, res) {    var userInDatabase = {        username:detail[0].username,        userId:detail[0].id,        phone:detail[0].phone,        email:detail[0].email    }    console.log("user in database :");    console.log(userInDatabase);    req.session.logged_in = 1;    req.session.username = req.body.username;    showInfo(userInDatabase, res);}function infoPage(res, userDetail, errorInfoDetail) {    res.render('info.ejs', {        username:userDetail[0].username,        userId:userDetail[0].id,        phone:userDetail[0].phone,        email:userDetail[0].email,        errorInfo:errorInfoDetail    })}function showInfo(user, res) {    res.render('info.ejs', {        username:user.username,        userId:user.id,        phone:user.phone,        email:user.email,        errorInfo:'用户详情'    });}function checkDataRep(user, flag, req, res) {// 逐一验证储存的信息是否重复    var testUsername = {username:user.username};    var testId = {id:user.id};    var testPhone = {phone:user.phone};    var testEmail = {email:user.email};    User.find(testUsername, function (err, detail) {        if (detail.length) {            flag.one = 0;            errorInfo = errorInfo + "用户名重复\n";        }    })    User.find(testId, function (err, detail) {        if (detail.length) {            flag.two = 0;            errorInfo = errorInfo + "id重复\n";        }    })    User.find(testPhone, function (err, detail) {        if (detail.length) {            flag.three = 0;            errorInfo = errorInfo + "电话号码重复\n";        }    })    User.find(testEmail, function (err, detail) {        if (detail.length ) {            flag.four = 0;            errorInfo = errorInfo + "邮箱重复\n";        }        dealWithDataSubmited(user, flag, req, res)    })}function repreload(res) {    res.render('index.ejs',{        errorInfo:errorInfo    })}

源码地址

github


总结

其实这一次的后端代码其中逻辑处理是比较复杂的,存在很大的优化空间,提高代码的可读性.而使用express框架和mongodb数据库模型的时候对一些api的时候来完成相应功能,是比较方便而且高效,其功能的强大远远不止于此。而对于项目的构建,可采用

express -e myapp

来生成目录,(-e表示ejs模板)

0 0
原创粉丝点击