You辉编程_NodeJS+MongoDB登录&注册后端开发

1.需求分析
# 需求很重要
-需求:描述项目最终效果的文字和图
-产品经理写需求,然后要经过各个项目角色的评审通过
-需求一般包括:原型图,功能描述
# 原型图
-注册页
-登录页
-主页
# 功能描述
-用户名唯一,不能重复注册
-用户名和密码匹配,即可登录
-登录成功后,跳转到首页
-非登录用户不能进入首页,登录用户可发布留言
-可产看全部留言,或查看自己的留言
-只能编辑和删除自己的留言,无权操作他人留言
2.数据库设计
# mongodb创建数据库
-创建数据库comment
-创建comments,存储留言数据
-创建users,存储用户
# mongoose定义Schema和Model
-回顾mongoose
-定义Schema
-定义Model
3.接口(路由)设计
# 需要哪些接口?
-注册
-登录 
-获取留言
-创建留言
-更新
-删除
# 哪些接口需要登录验证?
-登录不需要
-注册不需要
-其他都需要
# 登录如何实现(跨域传递cookie)
4.初始化开发环境
# 初始化koa2环境
-安装脚手架: npm install -g koa-generator
-项目命名并生成环境: koa2 messageitem 
-进入项目: cd Item 
-安装所有依赖文件: npm install
-在根目录新建src文件,把public、routers、views、app.js移入src中
# 规范目录和层级
-路由-->controller-->db-->数据库 
   |             |
 中间件         Model
# 连接数据库
-安装mongoose npm install mongoose --save
-连接mongodb
-Schema和Model
5.项目开发
# 前端代码
# 跨域&跨域传递cookie
-需要插件: npm i koa2-cors --save
-登录需要设置session:需要插件:npm install koa-generic-session --save
# 接口开发&前后端联调

 

 

/**入口文件及配置 app.js*/
const Koa = require('koa')
const app = new Koa()
const views = require('koa-views')
const json = require('koa-json')
const onerror = require('koa-onerror')
const bodyparser = require('koa-bodyparser')
const logger = require('koa-logger')
const cors = require('koa2-cors')
const session = require('koa-generic-session')

const index = require('./routes/index')
const users = require('./routes/users')
const comment = require('./routes/comment')

// error handler
onerror(app)

//允许服务端支持跨域
app.use(cors({
  origin: 'http://localhost:8080', // 支持前端哪个域,可以跨域
  credentials: true // 允许跨域的时候带着 cookie
}))

//配置 session
app.keys = ['yyhZDMY^1024'];//设置密钥,携带在cookie
app.use(session({
  path:'/',
  httpOnly: true,//只允许服务端来操作cookie
  maxAge: 24 * 60 * 60 * 1000
}))

// middlewares
app.use(bodyparser({
  enableTypes:['json', 'form', 'text']
}))
app.use(json())
app.use(logger())
app.use(require('koa-static')(__dirname + '/public'))

app.use(views(__dirname + '/views', {
  extension: 'pug'
}))

// logger
app.use(async (ctx, next) => {
  const start = new Date()
  await next()
  const ms = new Date() - start
  console.log(`${ctx.method} ${ctx.url} - ${ms}ms`)
})

// routes
app.use(index.routes(), index.allowedMethods())
app.use(users.routes(), users.allowedMethods())
app.use(comment.routes(), comment.allowedMethods())

// error-handling
app.on('error', (err, ctx) => {
  console.error('server error', err, ctx)
});

module.exports = app

 

//db.js
//连接数据库的处理模块(Module)
const mongoose = require('mongoose');

const url = 'mongodb://localhost:27017';
const dbName = 'comment3';

//配置
// mongoose.set('useCreateIndex',true);
// mongoose.set('useFindAndModify',false);

//开始连接
mongoose.connect(`${url}/${dbName}`,{
    useNewUrlParser: true,
    useUnifiedTopology: true
});

//获取连接所需要的信息提示connection对象
const conn = mongoose.connection;

//连接错误处理
conn.on('error',err =>{
    console.log('mongodb 连接失败',err);
})

//把连接数据的一些处理module导出去
module.exports = mongoose;
/*model-Schema*/
//Comment.js
//留言的数据库模型
const mongoose = require('../db/db');

const CommentSchema = mongoose.Schema({
    content: {
        type: String,
        required: true
    },
    username: String,
}, { timestamps:true })

//mongoose会自动把comment collection创建出来
const Comment = mongoose.model('comment',CommentSchema);

module.exports = Comment;


/**User.js**/

//用户的数据库模型(module)
const mongoose = require('../db/db');

const UserSchema = mongoose.Schema({
    username: {
        type: String,
        required: true,
        unique: true //唯一
    },
    password: String,
    age: Number,
    city: String,
    gender: {
        type: Number,
        default: 0 //0-保密,1-男,2-女
    }
}, { timestamps: true });

//通过mongoose.mode把上面的处理定义成模型
const User = mongoose.model('user',UserSchema);

module.exports = User;
/**router路由代码*/
/*comment.js*/
//留言功能的路由
const router = require('koa-router')();
const loginCheck = require('../middleware/loginCheck');
const { create, getList, del, update } = require('../controller/comment');

router.prefix('/comment');

//更新留言
router.post('/update',loginCheck,async(ctx, next)=>{
    //获取id , content
    const{ _id, content } = ctx.request.body;
    //获取用户名
    const { username } = ctx.session.userInfo;
    //执行更新
    try{
        const newData = await update(_id, username, content);
        ctx.body = {
            errno: 0,
            data: newData
        }
    }catch(ex){
        console.error('更新失败',ex);
        ctx.body = {
            errno: -1,
            message: '更新失败'
        }
    }
})

//删除留言
router.post('/del',loginCheck,async(ctx,next)=>{
    //获取id
    const { _id } = ctx.request.body;
    //获取用户名
    const { username } = ctx.session.userInfo;
    //执行删除(交给controller处理)
    try{
        await del(_id, username);
        ctx.body = {
            errno: 0,
        }
    }catch(ex){
        //失败
        console.error('删除失败',ex);
        ctx.body = {
            errno: -1,
            message: '删除失败'
        }
    }
})

//获取留言列表
router.get('/list',loginCheck,async(ctx,next)=>{
    //获取filterType = 1查看全部,2查看自己
    let { filterType } = ctx.query;
    filterType = parseInt(filterType) || 1;

    //获取当前用户名
    let username = '';
    if(filterType == 2) {
        username = ctx.session.userInfo.username;
    }

    //获取留言列表
    const list = await getList(username);
    ctx.body = {
        errno: 0,
        data: list
    }
})

//插入新留言
router.post('/create',loginCheck,async(ctx,next)=>{
    //获取留言内容
    const { content } = ctx.request.body;
    //从session中获取用户
    const { username } = ctx.session.userInfo;
    //提交留言,其功能交给controller处理
    const newComment = await create(content, username);

    //返回
    ctx.body = {
        errno: 0,
        data: newComment
    }
})

module.exports = router;

/**index.js*/
const router = require('koa-router')()

router.get('/', async (ctx, next) => {
  await ctx.render('index', {
    title: 'Hello Koa 2!'
  })
})

router.get('/string', async (ctx, next) => {
  ctx.body = 'koa2 string'
})

router.get('/json', async (ctx, next) => {
  ctx.body = {
    title: 'koa2 json'
  }
})

module.exports = router

/*users.js*/
const router = require('koa-router')()
const { register,login } = require('../controller/user');
const loginCheck = require('../middleware/loginCheck');

router.prefix('/users');//前缀

//获取用户信息之前先进行登录校验
router.get('/getUserInfo',loginCheck, async(ctx, next)=>{
  ctx.body = {
    errno: 0,
    data: ctx.session.userInfo
  }
})

//登录路由
router.post('/login',async(ctx,next)=>{
  //获取登录信息
  const { username, password } = ctx.request.body;
  //验证登录(让controller处理)
  const res = await login(username, password); //调用controllor
  if(res){
    //登录成功需要设置session(即在session存什么)
    ctx.session.userInfo = {
      username
    }
    ctx.body = {
      errno: 0
    }
  }else{
    ctx.body = {
      errno: -1,
      message: '登录失败'
    }
  }
})

//注册路由
router.post('/register',async(ctx, next)=>{
  //获取注册信息(前端传过来的)
  const userInfo = ctx.request.body;
  /*提交注册(即把获取的注册信息放到数据库里),把注册功能交给controller(多一层结构更清晰),里定义一个注册功能,
  然后引入这个功能(是一个函数)*/
  try{
    const newUser = await register(userInfo);//调用controller
    ctx.body = {
      errno: 0,
      data: newUser
    }
  } catch(ex){
    console.error('注册失败',ex);
    ctx.box = {
      errno: -1,
      message: '注册失败'
    }
  }
})

module.exports = router
/**middleware中间件*/
/*loginCheck.js*/

//登录验证的中间件
async function loginCheck(ctx, next){
    const session = ctx.session || {}
    const userInfo = session.userInfo
    if(userInfo && userInfo.username){
        //登录验证成功
        await next();
        return;
    }else{
        //登录验证失败
        ctx.body = {
            errno: -1,
            message: '用户尚未登录'
        }
    }
}

module.exports = loginCheck;
/*Controller控制器*/
/**user.js*/
//user controller
const User = require('../model/User');

//登录功能
async function login(username, password){
    //从数据查找是否存在
    const user = await User.findOne({username,password});
    if(user !== null){
        //说明在数据库找到了
        //登录成功
        return true;//返回给routes/users.js
    }else{
        //登录失败
        return false;
    }
}

//注册的功能
async function register(userInfo = {}){
    //userInfo存储了注册信息

    //把userInfo存入数据库
    const newUser = await User.create(userInfo);
    //返回注册的用户信息
    return newUser;
}

module.exports = {
    register,
    login
}


/*comment.js*/

const Comment = require('../model/Comment')

//更新留言
async function update(_id, username, content){
    const newData = await Comment.findOneAndUpdate(
        { _id, username }, //更条件
        { content }, //更新内容
        { new: true } //返回更新后的留言
    )
    return newData;
}

//删除留言
async function del(_id, username){
    await Comment.remove({
        _id,
        username //只能删除自己的留言
    })
}

//获取留言列表
async function getList(username = ''){
    const whereOpt = {}
    if(username){
        whereOpt.username = username;
    }
    const list = await Comment.find(whereOpt).sort({_id: -1});
    return list;
}

//创建留言的数据库
async function create(content, username){
    //创建数据库后并保存到数据库
    const newComment = await Comment.create({
        content,
        username
    })
    return newComment
}

module.exports = {
    create,
    getList,
    del,
    update
}

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值