我们从上次创建 koa 到了现在 也有一段 时间了 ,来写一下登录、注册吧
启动服务
首先 , 我们先来启动一下我们的服务
注意:
我这里显示了数据库连接成功 我们在 去启动koa服务的时候 要先去 开启我们的数据库 这样才可以连接到数据库
配置数据模型
数据模型 就是我们数据库接受的数据,以及数据的数据类型
创建一个model文件夹 里面创建一个UserModel.js的文件 (名称可以自定义)
const mongoose = require('mongoose');
//将 Schema model 解构出来
const { Schema, model } = mongoose;
//创建数据模型
// type:数据类型
// default:默认值
// required:是否必填
// select:是否在返回数据里面进行显示
const csdnSchema = new Schema({
__v: { type: String, select: false },
name: { type: String, required: true },
email: { type: String, default: '' },
password: { type: String, required: true },
date: { type: Date, default: Date.now } // 注册时间
})
//连接的数据库里的文件名称
module.exports = model('csdnReg', csdnSchema)
注意
app.js
mongoose.connect('mongodb://localhost/king'); var db = mongoose.connection; db.on('error', console.error.bind(console, '连接失败!!!')); db.once('open', function () { console.log('连接成功!!!') });
这里的mongoose.connect('mongodb://localhost/king') 是我们连接数据库的文件夹名称 数据模型文件 数据是存在这里 (king/csdnReg)
配置注册路由
routers/user.js
const Router = require('koa-router');
const router = new Router({prefix:'/user'});
const {User,register}=require('../controllers/userDemo')
router.get('/',User)
router.post('/register',register)
module.exports=router
controllers/userDemo.js
const csdnUser=require('../model/UserModel')
const User=async ctx=>{
ctx.body="我是User页面"
}
const register=async ctx=>{
//在进行post路由配置的时候客户端利用data传参
// 服务器端利用ctx.request.body接收传递的参数
const {name,password,email}=ctx.request.body;
// 在数据库中进行查找和我们传递的email一样的数据
const findResult=await csdnUser.find({email})
//如果查找到了,返回用户已经存在
if(findResult.length){
ctx.body={status:200,msg:'用户已经存在'}
}else{
// 通过实例化 之后 的save方法 将数据存储到数据库
// 这里的await 不可以丢弃 否则 会存不到数据库里
//注册成功的用户信息将返回到客户端
ctx.body = await new csdnUser(ctx.request.body).save();
}
}
module.exports={User,register}
请求
在这里我使用的是Apipost 请求的
密码加密
在这里可以看到我们的返回密码 ,处于一个明文状态, 这样信息非常容易暴露,所以下面对密码进行了加密
安装加密插件
npm install bcryptjs
创建 bcrypt 文件夹 , 文件夹里面创建 index.js
bcrypt/index.js
var bcrypt = require('bcryptjs');
//密码加密
const passencrypt = (password) => {
var salt = bcrypt.genSaltSync(10);
var hash = bcrypt.hashSync(password, salt);
return hash
}
module.exports = {
passencrypt
}
controllers/userDemo.js
引入
const {passencrypt}=require('../bcrypt/index')
使用
const register=async ctx=>{
//在进行post路由配置的时候客户端利用data传参
// 服务器端利用ctx.request.body接收传递的参数
const {name,password,email}=ctx.request.body;
// 在数据库中进行查找和我们传递的email一样的数据
const findResult=await csdnUser.find({email})
//如果查找到了,返回用户已经存在
if(findResult.length){
ctx.body={status:200,msg:'用户已经存在'}
}else{
//密码加密
ctx.request.body.password=passencrypt(password)
// 通过实例化 之后 的save方法 将数据存储到数据库
// 这里的await 不可以丢弃 否则 会存不到数据库里
ctx.body = await new csdnUser(ctx.request.body).save();
}
}
再次进行请求 可以看到密码已经进行了加密
登录
bcrypt/index.js 添加了解密password函数
//参数1:客户端传递过来的密码 参数2: 数据库里匹配数据的加密密码
const passdecode=(password,passwordencrypt)=>{
return bcrypt.compareSync(password, passwordencrypt); // true
}
配置登录路由
router.post('/login',Login)
Login是这里来的
const {User,register,Login}=require('../controllers/userDemo')
/controllers/userDemo.js 添加了Login 逻辑函数
const Login = async (ctx) => {
const { name, password, email } = ctx.request.body;
//判断客户端传过来的name参数 是否可以匹配到数据库里存储的数据
const findResult = await csdnUser.find({ name })
//匹配到了进行判断密码
if (findResult.length) {
//判断密码的函数
if(passdecode(password,findResult[0].password)){
ctx.body = { status: 200, msg: '验证成功' }
}
} else {
ctx.body = { status: 403, msg: '用户不存在' }
}
}
Token
一般在我们去请求后端的时候都回来给我们返回一个标识token , 好让我们在以后请求数据的时候去判断用户是否登录
.安装生成Token插件
npm install jsonwebtoken
安装好了插件让我们再来做一件事情
app.js
const {connection,serKey}=require('./mongoose/index')
mongoose.connect(connection);
var db = mongoose.connection;
db.on('error', console.error.bind(console, '连接失败!!!'));
db.once('open', function () {
console.log('连接成功!!!')
});
在连接数据库这里的代码当中 将 mongoose.connect(参数换成了变量) 变量是哪里来的呢
首先 我们创建一个 mongoose文件夹 里面创建一个 index.js 的文件
module.exports={
//连接数据库的地址
connection:'mongodb://localhost/king',
//生成token的时候需要的标识
serKey:'biaoma'
}
app.js 里的变量 就是这么来的
controllers/userDemo.js
引入
//插件
const jwt=require('jsonwebtoken')
//token标识
const {serKey}=require('../mongoose/index')
这个页面的 Login 函数:
const Login = async (ctx) => {
const { name, password, email } = ctx.request.body;
//判断客户端传过来的name参数 是否可以匹配到数据库里存储的数据
const findResult = await csdnUser.find({ name })
//匹配到了进行判断密码
if (findResult.length) {
//判断密码的函数
if(passdecode(password,findResult[0].password)){
//传递的对象 //token标识 //有效时长
let token=jwt.sign(ctx.request.body,serKey, { expiresIn: '1h' });
ctx.body = { status: 200, msg: '验证成功',token }
}
} else {
ctx.body = { status: 403, msg: '用户不存在' }
}
}
Login请求