一、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; }