node 前后端登录(用户名,密码)连接mongoose操作方式
1.建模的User.js
const mongoose = require('mongoose') //引入Mongoose
const Schema = mongoose.Schema //声明Schema
let ObjectId = Schema.Types.ObjectId //声明Object类型
const bcrypt = require('bcrypt')
const SALT_WORK_FACTOR = 10
//创建我们的用户Schema
const userSchema = new Schema({
UserId: ObjectId,
userName: { unique: true, type: String },
password: String,
createAt: { type: Date, default: Date.now() },
lastLoginAt: { type: Date, default: Date.now() }
}, {
collection: 'user'
})
//每次存储数据时都要执行
//这个是用来注册的,可返还是否有重复的用户名
userSchema.pre('save', function (next) {
//let user = this
// console.log(this)
bcrypt.genSalt(SALT_WORK_FACTOR, (err, salt) => {
if (err) return next(err)
bcrypt.hash(this.password, salt, (err, hash) => {
if (err) return next(err)
this.password = hash
next()
})
})
})
//用来比对用户名相同,密码是否正确的
userSchema.methods = {
//密码比对的方法
comparePassword: (_password, password) => {
return new Promise((resolve, reject) => {
bcrypt.compare(_password, password, (err, isMatch) => {
if (!err) resolve(isMatch)
else reject(err)
})
})
}
}
//发布模型
mongoose.model('User', userSchema)
2.api里面的user.js 接口Js
const Router = require('koa-router')
const mongoose = require('mongoose')
let router = new Router()
router.get('/', async (ctx) => {
ctx.body = '用户首页'
})
router.post('/register', async (ctx) => {
const User = mongoose.model('User')
let newUser = new User({
userName: ctx.request.body.username,
password: ctx.request.body.password,
})
await newUser.save().then(() => {
ctx.body = {
code: 200,
message: '注册成功'
}
}).catch(err => {
ctx.body = {
code: 500,
message: err
}
})
})
router.post('/login', async (ctx) => {
let userInfo = ctx.request.body
let userName = userInfo.userName
let password = userInfo.password
//引入User的model
const User = mongoose.model('User')
await User.findOne({ userName: userName }).exec().then(async (res) => {
console.log(res)
if (res) {
//当用户名存在时,开始比对密码
let newUser = new User() //因为是实例方法,所以要new出对象,才能调用
// comparePassword 是schema/底下User.js 下面实例化的方法
// res.password 是数据库中的password
await newUser.comparePassword(password, res.password)
.then((isMatch) => {
//返回比对结果
ctx.body = { code: 200, message: isMatch }
})
.catch(error => {
//出现异常,返回异常
console.log(error)
ctx.body = { code: 500, message: error }
})
} else {
ctx.body = {
code: 201,
message: '用户名不存在'
}
}
})
})
module.exports = router
3.index.js 主js 初始化
const Koa = require('koa')
const app = new Koa()
//连接数据库初始化
const { connect,initSchemas } = require('../service/database/init')
const mongoose = require('mongoose')
const Router =require('koa-router')
// 作为post请求用 koa-bodyparser
const bodyParser = require('koa-bodyparser');
app.use(bodyParser());
// 支持跨域
const cors = require('koa2-cors')
app.use(cors())
let user = require('./appApi/user')
//装载子路由
let router = new Router();
router.use('/user',user.routes())
//加载路由中组件
app.use(router.routes())
app.use(router.allowedMethods())
//立即执行函数
;(async () => {
// 第四个文件夹有方法
await connect()
initSchemas()
})()
app.use(async (ctx) => {
ctx.body = '<h1>Hello Koa2</h1>'
})
app.listen(3000, () => {
console.log('3000端口打开')
})
4.连接数据库初始化文件 init.js
const mongoose = require('mongoose')
const db = 'mongodb://localhost/smile-db'
// 需要安装glob 插件,之前笔记有设计
const glob = require('glob')
const {resolve} = require('path')
exports.initSchemas = () =>{
glob.sync(resolve(__dirname,'./schema/','**/*.js')).forEach(require)
}
mongoose.Promise = global.Promise
exports.connect = () => {
//链接数据库
mongoose.connect(db)
let maxNum = 0
return new Promise((resolve, reject) => {
//增加数据库监听事件
//数据库监听断开事件
mongoose.connection.on('disconnected', (err) => {
console.log('************数据库已断开***********')
if(maxNum <=3){
maxNum ++
mongoose.connect(db)
}else{
reject()
throw new Error('数据库出现问题,程序无法搞定,请维护')
}
})
//数据库监听链接错误事件
mongoose.connection.on('error', (err) => {
console.log('************数据库错误***********')
if(maxNum <=3){
maxNum ++
mongoose.connect(db)
}else{
reject(err)
throw new Error('数据库出现问题,程序无法搞定,请维护')
}
})
//数据库监听打开
mongoose.connection.once('open', () => {
console.log('************MongoDB 连接成功***********')
resolve()
})
})
}