一、KOA准备–搭建本地服务器
-
1、首先创建一个目录
koa-app
,用相关工具打开 -
- 使用
npm init --yes
命令生成package.json
文件 - 新建
app.js
- 使用
-
2、安装 KOA
npm install koa koa-router -s
-
3、在
app.js
中写入://引入模块 const Koa = require('koa'); const Router = require('koa-router'); //实例化 Koa、Router // 创建一个Koa对象表示web app本身: const app = new Koa(); const router = new Router(); //配置路由 app.use(router.routes()).use(router.allowedMethods()); //配置5000端口号 const port = process.env.PORT || 5000; //在5000端口监听 app.listen(port,()=>{ console.log('server started on'+ port) ; }); //使用路由跳转 router.get('/',async ctx=>{ ctx.body = { msg:'Hello koa interfaces'}; });
-
4、在
package.json
文件scripts
中配置:"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "node app.js", },
-
安装
nodemon
,使用npm install -g nodemon
命令,并修改:"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "node app.js", "nodemon": "nodemon app.js" },
-
二、KOA接口文档–连接 Mongodb 数据库
-
1、打开 https://mlab.com/ 注册或登录
mongodb+srv://ypjngup:@cluster0-ul3xn.mongodb.net/test?retryWrites=true&w=majority
这是后面要用到的链接地址,记得要修改
<password>
为你增加的user
密码。 -
2、安装
mongoose
npm install mongoose -s
-
3、在
app.js
文件中加入以下代码const Mongoose = require('mongoose'); //连接数据库 Mongoose.connect('mongodb+srv://ypjngup:[email protected]/test?retryWrites=true&w=majority') .then(()=>{ console.log('Mongodb Connect...'); }).catch(err=>{ console.log(err); });
三、KOA接口文档–创建测试接口和用户模型
-
1、新建文件夹
routers
,在此下面新建文件夹api
,再新建user.js
,这个文件是关于用户登录等信息的接口文件-
(1)在
user.js
中写入//引入路由 const Router = require('koa-router'); const router = new Router(); //test router.get('/test',async ctx=>{ ctx.status = 200; ctx.body = { msg:'user works....' } }); module.exports = router.routes();
-
(2)在
app.js
中导入user.js
并使用const users = require("./routers/api/users.js"); //配置路由地址 router.use('/api/users',users);
-
-
2、配置用户模型
-
(1)新建文件夹
models
,再新建User.js
,这个文件是关于用户登录等信息的模型 -
(2)在
User.js
中输入const mongoose = require('mongoose'); const Schema = mongoose.Schema; //实例化数据模板 const UserSchema = new Schema({ name:{ type: String, required: true }, email:{ type: String, required: true }, password:{ type: String, required: true }, avatar:{ type:String }, date:{ type: Date, default: Date.now() } }); module.exports = User = mongoose.model("users",UserSchema);
-
(3)在
users.js
中导入User.js
const User = require('../../models/User.js');
-
四、KOA接口文档–注册接口和调试工具
-
1、
- 安装
npm install koa-bodyparser -s
,koa请求体解析中间件 - 安装
npm i bcryptjs
,对密码进行加密
- 安装
-
2、在
app.js
中添加const bodyParser = require('koa-bodyparser'); const bcrypt = require('bcryptjs'); app.use(bodyParser());
-
3、在
users.js
中修改router.post('/register',async ctx=>{ //存储到数据库 const findResult = await User.find({email: ctx.request.body.email}); if(findResult.length > 0){ ctx.status = 500; ctx.body = { email: '邮箱已被占用', } } else { const newUser = new User({ name: ctx.request.body.name, email: ctx.request.body.email, password:ctx.request.body.password }); await bcrypt.genSalt(10, (err, salt)=> { bcrypt.hash(newUser.password, salt, (err, hash)=> { if(err) throw err; newUser.password = hash }); }); await newUser.save().then(user=>{ ctx.body = user; }).catch(err=>{ console.log(err); }); } });
五、KOA接口文档–全球公认头像的使用
-
1、安装
npm install gravatar
-
2、在
users.js
文件中加入const gravatar = require('gravatar');
在
const newUser = new User({});
之前加入const avatar = gravatar.url(ctx.request.body.email, {s: '200', r: 'pg', d: 'mm'});
注:
gravatar.url
会返回一个头像,如果在全球公认头像
中注册过,则会返回一张图片,如果没有,则返回一张灰色没有脸的图片
六、KOA接口文档–解决注册接口加密问题
即解决往数据库存储时密码依旧是明文的问题。将 users.js
中密码部分抽离出来。
-
1、在根目录下新建
config
文件夹,在文件夹下新建tools.js
,并在该文件中写入const bcrypt = require('bcryptjs'); const tools = { enbcrypt(password){ var salt = bcrypt.genSaltSync(10); var hash = bcrypt.hashSync(password,salt); return hash; } }; module.exports = tools;
并删除
users.js
文件中的const bcrypt = require('bcryptjs'); await bcrypt.genSalt(10, (err, salt)=> { bcrypt.hash(newUser.password, salt, (err, hash)=> { if(err) throw err; newUser.password = hash }); });
将修改为:
const tools = require("../../config/tools.js"); const newUser = new User({ name: ctx.request.body.name, email: ctx.request.body.email, avatar:avatar, password:tools.enbcrypt(ctx.request.body.password) });
七、KOA接口文档–登录接口
-
1、在
users.js
中添加//引入bcrypt const bcrypt = require('bcryptjs'); /** *@route POST api/users/login * @desc 登录接口地址 返回token * @access 接口是公开的 */ router.post('/login',async ctx => { //查询 const findResult = await User.find({ email: ctx.request.body.email}); //查询到的数据库的用户 const user = findResult[0]; //输入的密码 const password = ctx.request.body.password; //判断查没查到 if(findResult.length == 0){ ctx.status = 400; ctx.body = { email : '用户不存在'}; }else { //查验后验证密码 var result = await bcrypt.compareSync(password, user.password); if(result){ //返回token ctx.status = 200; ctx.body = { success: true }; }else { ctx.status = 400; ctx.body = { password: '密码错误!'}; } } });
八、KOA接口文档–生成token
-
1、安装
jsonwebtoken
npm install jsonwebtoken --save
-
2、在
users.js
中使用token
//引入 jsonwebtoken const jwt = require('jsonwebtoken'); //返回token const payload = { id:user.id, name: user.name, avatar: user.avatar}; const token = jwt.sign(payload,'secret',{ expiresIn: 3600});
九、KOA接口文档–passport验证token
验证邮箱密码、账号、token等是否正确
-
1、安装
koa-passport
npm install koa-passport --save
-
2、在
app.js
中写入//引入 koa-passport const passport = require('koa-passport'); app.use(passport.initialize()); app.use(passport.session());
-
3、在
config
文件夹下新建passport.js
文件,并在app.js
文件中回调//回调到 config 文件中 passport.js require('./config/passport.js')(passport);
-
4、安装
passport-jwt
,用于使用 JSON Web TOKEN 进行身份验证的 Passport 策略。npm install passport-jwt --save
-
5、在
passport.js
文件中写const JwtStrategy = require('passport-jwt').Strategy, ExtractJwt = require('passport-jwt').ExtractJwt; const opts = {}; opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken(); opts.secretOrKey = 'secret'; const mongoose = require("mongoose"); const User = mongoose.model("users"); module.exports = passport =>{ passport.use(new JwtStrategy(opts, async function(jwt_payload, done) { const user = await User.findById(jwt_payload.id); if(user){ return done(null,user); }else { return done(null,false); } })); };
-
6、在
user.js
中添加router.get('/current',passport.authenticate('jwt', { session: false }),async ctx=>{ ctx.body = { id: ctx.state.user.id, name: ctx.state.user.name, email: ctx.state.user.email, avatar: ctx.state.user.avatar } });
十、KOA接口文档–使用 validator 验证表单
-
1、新建
validation
文件夹,新建login.js
和register.js
文件,用于登录和注册的验证 -
2、安装
npm i validator --save
-
3、在
register.js
中写入:const validator = require('validator'); const isEmpty = require('./isEmpty.js'); module.exports = function validateRegisterInput(data){ let errors = {}; if(!validator.isLength(data.name,{min:2,max:30})){ errors.name = "名字的长度不能小于两位且不能超过30位"; } return { errors:errors, isValid: isEmpty(errors) } };
-
4、在当前文件夹下新建
isEmpty.js
, 并写入const isEmpty = value => { return value == undefined || value===null || (typeof value === "object") && Object.keys(value).length ===0 || (typeof value === 'string' && value.trim().length === 0); }; module.exports = isEmpty;
-
5、在
user.js
中引入//引入input验证 const validateRegisterInput = require('../../validation/register.js');
在
router.post('/register',async ctx=>{ }
中添加
const { errors,isvalid} = validateRegisterInput(ctx.request.body); //判断是否通过 if(!isvalid){ ctx.status = 400; ctx.body = errors; return ; }
十一、KOA接口文档–验证注册和登录的 input
-
1、在
register.js
中更改data.name = !isEmpty(data.name) ? data.name : ''; data.email = !isEmpty(data.email) ? data.email : ''; data.password = !isEmpty(data.password) ? data.password : ''; data.password2 = !isEmpty(data.password2) ? data.password2 : ''; if(!validator.isLength(data.name,{min:2,max:30})){ errors.name = "名字的长度不能小于两位且不能超过30位"; } if(validator.isEmpty(data.name)){ errors.name = '名字不能为空'; } if(!validator.isEmail(data.email)){ errors.email = '邮箱不合法'; } if(validator.isEmpty(data.email)){ errors.email = '邮箱不能为空'; } if(validator.isEmpty(data.password)){ errors.password = '密码不能为空'; } if(!validator.isLength(data.password,{min: 6,max: 30})){ errors.password = 'password的长度不能小于6位且不能超过30位'; } if(validator.isEmpty(data.password2)){ errors.password2 = 'password2不能为空'; } if(!validator.equals(data.password,data.password2)){ errors.password2 = '两次密码不一致'; }
-
2、在
login.js
写入const validator = require('validator'); const isEmpty = require('./isEmpty.js'); module.exports = function validateLoginInput(data){ let errors = {}; data.email = !isEmpty(data.email) ? data.email : ''; data.password = !isEmpty(data.password) ? data.password : ''; if(!validator.isEmail(data.email)){ errors.email = '邮箱不合法'; } if(validator.isEmpty(data.email)){ errors.email = '邮箱不能为空'; } if(validator.isEmpty(data.password)){ errors.password = '密码不能为空'; } if(!validator.isLength(data.password,{min: 6,max: 30})){ errors.password = 'password的长度不能小于6位且不能超过30位'; } return { errors:errors, isValid: isEmpty(errors) } };
并在
router.post('/login',async ctx => { }
加入
const { errors,isValid} = validateLoginInput(ctx.request.body); //判断是否通过 if(!isValid){ ctx.status = 400; ctx.body = errors; return; }