这是基于Koa2+MongoDB实现的一个简单用户注册登录例子,用node以及mongodb来写后端接口操作数据库对前端来说真的太友好了。
一、安装依赖
在我的个人项目中,用到了concurrently来进行前后端连载,只要开启一个命令即可同时运行vue项目以及node服务端接口,童鞋们可自行查阅一下资料。
npm install koa koa-bodyparser koa-json koa-router koa-static mongoose --save
二、创建服务器以及连接数据库
const koa = require('koa');
const KoaRouter = require('koa-router');
const app = new koa();
const router = new KoaRouter();
//引入json
const json = require('koa-json');
//解析post请求
const bodyParser = require('koa-bodyparser');
//引入mongoose数据库
const mongoose = require('mongoose');
//配置静态图片 否则koa-multer上传图片后在浏览器无法查看图片
const staticFiles = require('koa-static');
const path = require('path');
//引入users数据表
const User = require('./model/User');
//中间件
app.use(json());
app.use(bodyParser());
//注意 访问时不需要增加/public前缀
app.use(staticFiles(path.join(__dirname, './public')));
//配置路由模块
app.use(router.routes()).use(router.allowedMethods());
//封装接口
router.use('/api/users', require('./routers/user'));
//连接数据库 数据库名webstack
mongoose.connect('mongodb://localhost:27017/webstack', {useNewUrlParser: true, useUnifiedTopology: true}).then(()=>{
console.log('数据库连接成功');
//监听端口
app.listen(8888, () => {
console.log('服务端已开启: http://localhost:8888')
})
}).catch(()=>{
console.log('数据库连接失败');
}
)
三、定义用户数据类型
在mongodb中使用schema来定义数据模型骨架,再通过model来创建mongodb中对应的集合。简单的来说,schema用来定义数据类型如name字段为number类型,再通过model就可以对数据库进行增删改查。
//model/user.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
//定义数据类型
const userSchema = new Schema({
email: {
type: String,
require: true
},
password: {
type: String,
require: true
},
isAdmin: {
type: Boolean, //是否是管理员
default: false //默认false 管理员身份修改数据库即可
},
date: {
type: Date,
default: Date
}
})
//基于数据结构创建一个叫User的表(首字母大写) 数据库中自动生成叫users
module.exports = mongoose.model('User', userSchema);
四、用户注册接口
先判断用户是否已被注册,被注册则返回提示,否则再把数据插入数据库。
//routers/user.js
const KoaRouter = require('koa-router');
const router = new KoaRouter();
//引入users数据表
const User = require('../model/User');
/**
* @route POST api/users/register
* @desc 注册接口地址
* @access 接口是公开的 即不需要token
*/
router.post("/register", async ctx => {
//接收参数 post
console.log(ctx.request.body);
const findResult = await User.find({
email: ctx.request.body.email
});
console.log(findResult);
//判断是否存在该用户
if(findResult.length > 0){
//状态码
ctx.status = 400;
ctx.body = {
status: 400,
message: "邮箱已经被占用"
}
}else{
//存储到数据库
const newUser = new User({
password: ctx.request.body.password,
email: ctx.request.body.email
})
//返回给客户端 一定要await 否则会返回Not Found
await newUser.save().then(user =>{
console.log(user);
ctx.status = 200;
ctx.body = {
status: 200,
message: "注册成功",
userInfo: user
}
}).catch(err =>{
console.log(err);
})
}
})
五、用户登录接口
先判断用户是否存在,不存在则返回提示,否则进行密码验证。
/**
* @route POST api/users/login
* @desc 登录接口地址 返回token
* @access 接口是公开的 即不需要token
*/
router.post("/login", async ctx => {
//接收参数 post
console.log(ctx.request.body);
const findResult = await User.find({
email: ctx.request.body.email
});
console.log(findResult);
if(findResult.length == 0){
ctx.status = 404;
ctx.body = {
status: 404,
message: "用户不存在"
}
}else{
//验证密码是否正确
var result = await User.find({password: ctx.request.body.password});
if(result.length > 0)){
//返回用户信息
ctx.status = 200;
ctx.body = {
status: 200,
message: "登录成功",
userInfo: findResult[0]
}
}else{
ctx.status = 400;
ctx.body = {
status: 400,
message: "密码错误"
}
}
}
})
六、前端调用接口
前端使用技术基于vue全家桶+typescript+element-ui。
//login.vue
handleSubmit(): void {
//表单验证
(this.$refs["ruleFormEle"] as any).validate((valid: Boolean) => {
console.log(valid);
if (valid) {
this.isLogin = true;
console.log("验证通过");
(this as any).$axios
.post("/api/users/login", this.ruleForm)
.then((res: any) => {
console.log(res);
})
.catch((err: any) => {
this.isLogin = false;
});
} else {
console.log("验证不通过");
}
});
}
七、效果图













网友评论