sever -》 数据库目录
config.js是数据库的连接和配置文件
models可以理解为存放各个 表的操作
export default {
dbs:'mongodb://127.0.0.1:27017/student',
//mongoDB数据库
redis:{
get host(){
return '127.0.0.1'
},
get port(){
return 6379
}
},
//redis数据库
smtp:{
get host(){
return 'smtp.qq.com'
},
get user(){
return '**@qq.com'
},
// pass码是qq邮箱给提供的。
get pass(){
return ''
},
//code是随机的四位数
get code(){
return ()=>{
return Math.random().toString(16).slice(2,6).toUpperCase()
}
},
//redis中可以使用expire命令设置一个键的生存时间,到时间后redis会自动删除它
get expire(){
return ()=>{
return new Date().getTime()+60*60*1000
}
}
}
//qq邮箱服务,发送验证码
}
//与get有关的都是redis数据库操作
登陆需要存储的字段有管操作
//dbs > User.js
import mongoose from 'mongoose'
const Schema = mongoose.Schema
const UserSchema=new Schema({
username:{
type:String,
unique:true,
require:true
},
password:{
type:String,
require:true
},
email:{
type:String,
require:true
}
})
export default mongoose.model('User',UserSchema)
上面已经配置好了数据库,接下来我们看看接口
import Router from 'koa-router';
//
import Redis from 'koa-redis'
//redis效率高一点,所以验证码发送用redis
import nodeMailer from 'nodemailer'
//用nodeMailer插件来发送邮件。
import User from '../dbs/models/users'
// USer模型,来操作mongodb
import Passport from './utils/passport'
//来引入passprot中间件
import Email from '../dbs/config'
//用来发邮件的配置参数
import axios from './utils/axios'
接口:axios来请求数据
let router = new Router({prefix: '/users'})
//创建以/users开始的路由
let Store = new Redis().client
//创建一个redis仓库
// 导出router
export default router;
发送验证码的接口
router.post('/verify', async (ctx, next) => {
let username = ctx.request.body.username
const saveExpire = await Store.hget(`nodemail:${username}`, 'expire')
if (saveExpire && new Date().getTime() - saveExpire < 0) {
ctx.body = {
code: -1,
msg: '验证请求过于频繁,1分钟内1次'
}
return false
}
let transporter = nodeMailer.createTransport({
service: 'qq',
auth: {
user: Email.smtp.user,
pass: Email.smtp.pass
}
})
let ko = {
code: Email.smtp.code(),
expire: Email.smtp.expire(),
email: ctx.request.body.email,
user: ctx.request.body.username
}
let mailOptions = {
from: `"认证邮件" <${Email.smtp.user}>`,
to: ko.email,
subject: '登陆注册码',
html: `您的邀请码是${ko.code}`
}
await transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log(error)
} else {
Store.hmset(`nodemail:${ko.user}`, 'code', ko.code, 'expire', ko.expire, 'email', ko.email)
}
})
ctx.body = {
code: 0,
msg: '验证码已发送,可能会有延时,有效期1分钟'
}
})
注册接口
router.post("/signup", async ctx => {
// 先获取表单里的信息,这么写是es6的解构赋值语法
const { username, password, email, code } = ctx.request.body;
if (code) {
const saveCode = Store.hget(`nodemail:${username}`, "code");
const saveExpire = Store.hget(`nodemail:${username}`, "expire");
if (saveCode == code) {
//redis数据库数据对比
if (new Date().getTime() - saveExpire > 0) {
ctx.body = {
code: -1,
msg: "验证码已过期,请重新尝试"
};
return false;
}
} else {
ctx.body = {
code: -1,
msg: "请填写正确的验证码"
};
}
} else {
ctx.body = {
code: -1,
msg: "未输入验证码"
};
}
let user = await User.find({ username });
if (user.length) {
ctx.body = {
code: -1,
msg: "已被注册"
};
return;
}
let nuser = await User.create({ username, password, email });
console.log(nuser);
if (nuser) {
ctx.body = {
code: 0,
msg: "注册成功"
};
} else {
ctx.body = {
code: -1,
msg: "注册失败"
};
}
});
登录接口
import passport from 'koa-passport'
import LocalStrategy from 'passport-local'
import UserModel from '../../dbs/models/users'
//passport引入本地策略
passport.use(new LocalStrategy(async function(username,password,done){
//三个参数分别是 用户名密码和回调
let where = {
//此处用where是表示搜索的时候参数是一个对象
username
};
let result = await UserModel.findOne(where)
if(result!=null){
if(result.password===password){
return done(null,result)
}else{
return done(null,false,'密码错误')
}
}else{
return done(null,false,'用户不存在')
}
}))
passport.serializeUser(function(user,done){
done(null,user)
})
passport.deserializeUser(function(user,done){
return done(null,user)
})
export default passport
router.post('/signin', async (ctx, next) => {
return Passport.authenticate('local', function(err, user, info, status) {
if (err) {
ctx.body = {
code: -1,
msg: err
}
} else {
if (user) {
ctx.body = {
code: 0,
msg: '登录成功',
user
}
return ctx.login(user)
} else {
ctx.body = {
code: 1,
msg: info
}
}
}
})(ctx, next)
})