数据加密是为了让用户数据得到有效并且可靠的保障,我想谁都不希望自己的银行取款密码被别人知道吧?在Node服务端,我们可以采用Bcrypt这个模块来给我们的用户敏感信息做加密和校验。下面以用户注册和登录来说说bcrypt的使用。

安装模块

我们先来把基本的环境搭好:

1
$ yarn add koa koa-router monk bcrypt

我这里是一次性安装所需的依赖模块,monk是用来连接MongoDB的。

创建服务

我们先创建一个服务 - app.js:

1
2
3
4
5
6
7
8
const Koa = require('koa');
const Server = new Koa();
const Router = require('./routes');

Server.use(Router.routes());
Server.listen(3000, () => {
console.log(chalk.cyan(`Server is running on port: 3000`));
});

再来添加我们要的api路由 routes.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
const Router = require('koa-router');
const router = new Router();
const { validate, enbcrypt } = require('./bcrypt');
router.get('/add', async (ctx, next) => {
let { username, password } = ctx.params;
let err = {
code: '3000',
info: ''
};
if (!username) {
err.info = '账号不能为空';
ctx.body = JSON.stringify(err);
return;
}
if (!password) {
err.info = '密码不能为空';
ctx.body = JSON.stringify(err);
return;
}
await AddUser({
username,
password: await enbcrypt(password)
}).then(res => {
ctx.body = JSON.stringify({
code: '1000',
info: '添加成功'
});
}).catch(() => {
err.info = '添加失败';
ctx.body = JOSN.stringify(err);
});
await next();
}).get('/login', async (ctx, next) => {
let { username, password } = ctx.params;
let err = {
code: '3000',
info: ''
};
if (!username) {
err.info = '账号不能为空';
ctx.body = JSON.stringify(err);
return;
}
if (!password) {
err.info = '密码不能为空';
ctx.body = JSON.stringify(err);
return;
}
await CheckUsnPsw({ username }).then(doc => {
validate(password, doc).then(res => {
console.log(res);
if (res) {
ctx.body = JSON.stringify({
code: '1000',
info: '登录成功'
});
return;
}
throw new Error();
}).catch(() => {
err.info = '账号或密码错误';
ctx.body = JSON.stringify(err);
});
}).catch(() => {
err.info = '账号或密码错误';
ctx.body = JSON.stringify(err);
});
});

  • /add:添加用户
  • /login:用户登录

处理Bcrypt加密和校验

如上代码里面我们其实已经引入了bcrypt这个模块了,那现在我们把bcrypt.js完善:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const bcrypt = require('bcrypt');
const saltRounds = 10;

const enbcrypt = async password => {
let salt = await bcrypt.genSaltSync(saltRounds);
return await bcrypt.hashSync(password, salt);
};

const validate = async (password, hash) => {
return await bcrypt.compareSync(password, hash);
};

module.exports = {
enbcrypt,
validate
};

连接MongoDB

我们使用monk将koa和MongoDB进行联通,实现数据的读写操作。
建一个mongo.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const Mhost = 'localhost:27017/local';
const db = require('monk')(Mhost);
const UserCollection = db.get('users');

// 添加用户
const AddUser = (data = {username: '', password: ''}) => {
return UserCollection.insert({username: data.username, psw: data.password}).then(res => {
db.close();
return res;
}).catch(() => {
db.close();
});
};

// 查询用户信息
const CheckUsnPsw = (query = { username: '' }) => {
return UserCollection.findOne({ username: query.username }).then(doc => {
db.close();
if (doc) {
return doc.psw;
}
throw new Error();
}).catch(() => {
db.close();
throw new Error();
});
};

到此,我们的程序业务逻辑已经写完了。然后yarn startnpm start重新启动服务!
在浏览器端先添加一个用户:

1
localhost:3000/add?username=test&password=123

这个如果业务没错,将显示添加成功。

这个时候我们去MongoDB查询一下该用户文档,会发现密码字段是一长串被加密后的字符。

下面我们再通过访问localhost:3000/login?username=test&password=123来验证一下登录是否成功,也就是校验密码是否正确。
不出意外,页面应该显示登录成功!

Bcrypt的官方文档点击这里查看