Skip to content

xiaohei-L/nodeDBTest3

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

39 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

说多了是泪,不说了 #基于 nodejs 和 mongoDb 的前后端分离开发 目录结构:

    ├── controllers     //数据库相关操作目录
    │   ├── base.js     //基础操作方法,此处我是封装了验证前端传来参数是否正确的方法
    │   ├── msgs.js     //相关业务逻辑代码,用于查询 /msgs 相关数据
    │   ├── user.js     //相关业务逻辑代码,用于查询 /users 相关数据
    ├── models          //通过 mongoose 创建数据库表格结构目录
    │   ├── msgs.js     //创建 msgs 表格
    │   ├── user.js     //创建 users 表格
    ├── routers         //路由的相关配置目录
    │   ├── index.js
    ├── schemas         //通过 mongoose 定义表格结构和相关操作和查询方法目录
    │   ├── msgs.js     //定义 msgs 表格的数据结构和相关方法
    │   ├── users.js    //定义 users 表格的数据结构和相关方法
    ├── app.js          //项目的入口文件
    ├── package.json
    ├── README.md

##起步:项目入口文件 app.js

var express = require('express')
var bodyParser = require('body-parser')
var cookieParser = require('cookie-parser')
var cookieSession = require('cookie-session')
var mongoose = require('mongoose')

var app = express()

app.set('port', process.env.PORT || 3000)

//这里用户登录的账号,直接存到session里了
app.use(cookieParser())
app.use(cookieSession({
    name: 'session',
    secret: 'Harvey',
    keys: ['key1', 'key2'],
    // Cookie Options
    maxAge: 24 * 60 * 60 * 1000 // 24 hours
}))

//通过 mongoose 连接数据库,因数据库加密授权了,需要加上用户名和密码
var dbUrl = 'mongodb://name:password@localhost/test'
mongoose.connect(dbUrl)
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
  console.log('mongoose opened!');
});

//使用 body-parser 模块,我们就可以通过 req.body 获取前端传过来的数据
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false }))

//设置跨域访问
app.all('*', function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");//设置来源域名,*表示所有的都可以请求(危险)
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Conten-Type, Accept");
    res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
    res.header("X-Powered-By",' 3.2.1')
    res.header("Content-Type", "application/json;charset=utf-8");
    next();
});

//引入 ./routers/index.js 中的相关路由配置
var index = require('./routers/index')
app.use('/', index);

app.listen(3000);
console.log('server 3000');

module.exports = app;

##运行项目

先安装 supervisor 提高 nodejs 调试效率

安装相关依赖 npm isntall

建议使用淘宝镜像 cnpm 安装比较快

安装完毕,运行项目 supervisor app.js

浏览器输入 localhost:3000 当然这时候还没啥东西的啦!因为还没配置相关路由嘛...

##接下来:配置相关路由 ./routers/index.js

var express = require('express')
var router = express.Router()
var User = require('../controllers/user')
var Msgs = require('../controllers/msgs')
var Base = require('../controllers/base')

var home = [
    { name: 'home', description: '我是首页', price: 12.12},
    { name: 'home', description: '我是首页', price: 12.12}
]

//先是配置 /,是 get 方式
//运行项目,浏览器输入 localhost:3000 就好返回上面定义的 home 数组了
router.get('/', checkLogin)
router.get('/', function(req, res) {
  res.json(home)
});

//用户注册、登录、注销登录的相关路由
//匹配相关路由,调用controllers 中相关的方法
router.post('/reg', User.showSignup)
router.post('/login', User.showSignin)
router.get('/users', User.showUsers)
router.get('/logout',User.logout)

router.get('/msgs', Msgs.showMsgs)

//用于检测用户是否登录接口
router.get('/checkLogin', function(req, res) {
  if (req.session.user) {
    res.json({code: 1, msg: '已登录', name: req.session.user.name})
  } else {
    res.json({code: -1, msg: '未登录'})
  }
});

function checkLogin(req, res, next) {
    if (!req.session.user) {
      console.log('未登入')
    }
    next();
}
function checkNotLogin(req, res, next) {
    if (req.session.user) {
      console.log('已登入')
    }
    next();
}

module.exports = router

##操作数据库 以上只是介绍如何运行项目和路由的相关配置,并且是返回自己写的数据,那如何返回数据库的数据,并对数据进行增删改查呢?

先设计数据库表结构咯 使用 mongoose 在 schemas 目录创建相应的 js 文件 此处就以 uer.js 为例:

var mongoose = require('mongoose')

var bcrypt = require('bcryptjs')//一种加密算法,这里用来加密密码
var SALT_WORK_FACTOR = 10

//定义表格结构和相关数据类型
var UserSchema = new mongoose.Schema({
  name: {
    unique: true,
    type: String
  },
  password: String,
  //用户角色
  // 0: nomal user
  // 1: verified user
  // 2: professonal user
  // >10: admin
  // >50: super admin
  role: {
    type: Number,
    default: 0
  },
  meta: {
    createAt: {
      type: Date,
      default: Date.now()
    },
    updateAt: {
      type: Date,
      default: Date.now()
    }
  }
})

UserSchema.pre('save', function(next) {
  var user = this

  if (this.isNew) {
    this.meta.createAt = this.meta.updateAt = Date.now()
  }
  else {
    this.meta.updateAt = Date.now()
  }

  bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
    if (err) return next(err)

    bcrypt.hash(user.password, salt, function(err, hash) {
      if (err) return next(err)

      user.password = hash
      next()
    })
  })
})
//定义密码的比较方法,登录时需要用到
UserSchema.methods = {
  comparePassword: function(_password, cb) {
    bcrypt.compare(_password, this.password, function(err, isMatch) {
      if (err) return cb(err)

      cb(null, isMatch)
    })
  }
}

//定义相关的查询方法,需要时可以调用
UserSchema.statics = {
  fetch: function(cb) {
    return this
      .find({})
      .sort('meta.updateAt')
      .exec(cb)
  },
  findById: function(id, cb) {
    return this
      .findOne({_id: id})
      .exec(cb)
  }
}

module.exports = UserSchema

这里只是定义了表格,但是还没创建,接下来就是创建了 ./models/user.js

var mongoose = require('mongoose')
var UserSchema = require('../schemas/user')
//创建表格,表名为 users, 默认会加上 s
var User = mongoose.model('User', UserSchema)

module.exports = User

表格定义和创建好了,就剩操作了 ./controllers/user.js

var User = require('../models/user')
var Base = require('./base')

function Users(user) {
    this.name = user.name
}
//注册时调用该方法
exports.showSignup = function(req, res) {
    var _user = req.body
    //调用 ./base.js 中的方法,判断前端传来的参数是否正确
    var _params = ['name', 'password', 'passwordRepeat']
    var check = Base.checkParams(_user, _params)
    if(check === 1) {
        //注册时,判断用户是否已注册
        User.findOne({name:_user.name}, function(err, user) {
            if(err) {
                console.log(err);
            }
            if(user) {
                res.json({msg: '用户已存在', code: -1})
            } else {
                if(_user.password !== _user['passwordRepeat']) {
                    res.json({msg: '两次输入密码不一致', code: -1})
                } else {
                    var user = new User(_user);
                    user.save(function(err,user) {
                        if(err) {
                            console.log(err);
                        } else {
                            res.json({msg: '注册成功', code: 1})
                        }
                    })
                }
            }
        })
    } else {
        res.json(check)
    }
}
//显示总共有多少用户 /users
exports.showUsers = function(req,res) {
    User.find({}, function(err, user) {
        if(err) {
            console.log(err)
        }
        var users = []
        user.forEach(function(doc, index) {
            //实例化 doc 对象,我们只需要取 name 字段
            var user = new Users(doc)
        users.push(user);
        })
        res.json(users)
    })
}
//登录时调用的方法
exports.showSignin = function(req,res) {
    var _user = req.body;
    var _params = ['name', 'password']
    var check = Base.checkParams(_user, _params)
    var name = _user.name;
    var password = _user.password;

    if(check == 1) {
        User.findOne({name:name},function(err,user) {
            if(err) {
                console.log(err);
            }
            
            if(!user) {
                res.json({msg: '用户不存在', code: -1})
                // return res.redirect('/signup');
            }
            user.comparePassword(password,function(err,isMatch) {
                if(err) {
                    console.log(err);
                }
                
                if(isMatch) {
                    //登录成功后,会使用 session 保持登录态,session 的相关使用在 app.js 中有过介绍
                    req.session.user = user;
                    res.json({msg: '登陆成功', code: 1})
                } else {
                    res.json({msg: '密码不正确', code: -1})
                }
            })
        })
    } else {
        res.json(check)
    }
}

//注销登录时调用的方法,清除 session 清除登录态
exports.logout = function(req,res) {
    delete req.session.user;
    res.json({msg: '注销登陆成功', code: 1})
}

**至此,我们已经把用户登录、注册、注销登录和查询已注册用户的接口写好了。

接下来就是部署到服务器上了,这个留着下节再讲... 哈哈,我也还没弄懂很多,半桶水,只是简单部署到服务器,但数据库方面和 Nginx 方面还需研究,下次弄懂,再一起补充啦!

About

node 的 rest api 前后端分离开发

Resources

Stars

Watchers

Forks

Packages

No packages published