1.安装bcrypt 给密码加密
github bcrypt
2.utils内新建utils.js
const bcrypt = require('bcrypt')
// 加密
exports.hash = (plaintextPassword) => {
const saltRounds = 10
return new Promise(resolve => {
bcrypt.genSalt(saltRounds, function(err, salt) {
bcrypt.hash(plaintextPassword, salt, function(err, hash) {
resolve(hash)
})
})
})
}
// 对比
exports.compare = (myPlaintextPassword, hash) => {
return new Promise(resolve => {
bcrypt.compare(myPlaintextPassword, hash, function(err, result) {
resolve(result)
})
})
}
1.安装openssl 生成公钥和私钥
github openssl
// 生成私钥
genrsa -out rsa_private_key.pem 2048
// 根据私钥生成公钥
rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
之后放到keys文件夹内备用
2.安装jwt
github jsonwebtoken
utils内新建token.js 内容如下
const fs = require('fs')
const path = require('path')
const jwt = require('jsonwebtoken')
// 生成token方法
exports.sign = (payload) => {
var privateKey = fs.readFileSync(path.resolve(__dirname, '../keys/rsa_private_key.pem'));
var token = jwt.sign(payload, privateKey, { algorithm: 'RS256'});
return token
}
// 验证token方法
exports.verify = (token) => {
var cert = fs.readFileSync(path.resolve(__dirname, '../keys/rsa_public_key.pem')); // get public key
return new Promise(resolve => {
jwt.verify(token, cert, function(err, decoded) {
resolve(decoded)
})
})
}
配置好路由后 controller层内新建users.js
const userModel = require('../model/user')
const { hash, compare } = require('../utils/bcrypt')
const { sign } = require('../utils/token')
// 注册
const signup = async (ctx, next) => {
ctx.res.writeHead(200, {
'Content-Type': 'application/json; charset=utf-8'
})
// koa-bodyparser解析请求参数
let { username, password } = ctx.request.body
// 查找用户名是否已注册
let user = await userModel.findOne(username)
// 如果没有
if (!user) {
// bcrypt 加密
let newPassword = await hash(password)
// 入库
let result = await userModel.signup({username, password: newPassword})
if (result) {
ctx.render('success.art', {
data: JSON.stringify({
username: result.username
})
})
} else {
ctx.render('fail.art', {
message: JSON.stringify('注册失败。')
})
}
await next()
} else {
ctx.render('fail.art', {
message: JSON.stringify('用户名存在')
})
}
}
// 登录
const signin = async (ctx, next) => {
ctx.res.writeHead(200, {
'Content-Type': 'application/json; charset=utf-8'
})
let { username, password } = ctx.request.body
let result = await userModel.findOne(username)
// 根据用户名生成token
let token = sign({username})
if (result) {
// 对比两次密码
let ret = await compare(password, result.password)
if (ret) {
// koa 如何设置自定义首部?
ctx.res.writeHead( 200, {
'X-Access-Token': token
})
ctx.render('success.art', {
data: JSON.stringify({
username: result.username
})
})
} else {
ctx.render('fail.art', {
message: JSON.stringify('登录失败。')
})
}
} else {
ctx.render('fail.art', {
message: JSON.stringify('登录失败。')
})
}
}
// 退出
module.exports = {
signup,
signin,
signout
}