Vue博客搭建(5)数据库的搭建

171 阅读3分钟

我们在上一篇文章中写好了注册的接口,接下来打算完整地实现注册功能。

为了保存数据,我们需要一个数据库。对于小型的应用来说,其实使用sqlite3这样的轻量级数据库就可以了。但是为了让我们的技术栈更加贴近生产环境,我们这次使用MySQL来作为我们博客的数据库。

MySQL的安装与初始化

我们的服务器使用的是Debian,直接使用宝塔面板的软件商店就可以进行安装。在宝塔面板中也可以查看用户名和密码等事宜。

在node中连接到数据库

我们使用的是mysql包来进行MySQL和node的连接。我们先通过一个内部的server/createDatabase接口来创建一个数据表useraccount,包括一个用户名和密码,都是字符串varchar(length)类型。

const mysql = require('mysql')

const connection = mysql.createConnection({
    host: 'localhost', // 数据库的地址,我们这里就是本地连接
    user: 'root', // 用户名和密码,我们这里使用管理员用户
    password: 'admin',
    database: 'userdata' // 所连接的数据库名称,userdata数据库是之前在宝塔面板中创建好的
})
connection.connect();

app.get('/createDatabase',(req, res)=>{
    connection.query(`create table useraccount
                    (
                        username varchar(20),
                        password varchar(512)
                    )`,
    (err,res)=>{
        console.log(err);
    });
})

如何判断成功了?当你访问两次同样的路由你会发现会报错,因为数据表useraccount已经被创建完毕了。

密码加密

成功创建了数据库后我们就可以添加用户注册功能了,找到我们之前写的server/register路由,就可以接收到前端上传的用户名和密码了。

但是用户的密码直接通过明文存储在数据库中显然是不安全的,一定要通过一些手段进行加密。加密方式的演变这里不再阐述了,不了解的朋友可以参考粒粒姐的视频。我们这里要对后端存储的密码进行SHA512加密,这是一种目前安全性较高的加密方式。

加密使用的是crypto-js包,这个包支持很多的加密算法,包括MD5和我们今天要用的SHA512等。

const SHA512 = require('crypto-js/sha512');

app.post('/register',(req, res)=>{
    const username = req.body.username;
    let password = req.body.password;
    password = SHA512(password).toString();
    res.send(password);
})

使用Apifox添加一个快速请求,我们让其密码等于12345678,就能看到加密后的密文为fa585d89c851dd338a70dcf535aa2a92fee7836dd6aff1226583e88e0996293f16bc009c652826e0fc5c706695a03cddce372f139eff4d13959da6f1f5d3eabe,达到了加密的目的。

向数据库中插入数据

密码进行加密之后就可以放入数据库了。我们就再来学习一个SQL语句吧。insert into TABLE (param1, param2 ... paramn) values(?, ?, ... ?)代表着向TABLE表中写入这些参数,值会从values中顺序查找。

到了Node环境中,直接使用connection.query语句即可,注意query语句有三个参数,第一个参数是SQL语句,第二个参数是SQL语句的参数数组,最后一个参数便是回调函数(参数分别为errresfield)。

app.post('/register',(req, res)=>{
    const username = req.body.username;
    let password = req.body.password;
    password = SHA512(password).toString();
    const addSql=`insert into useraccount (username, password) values(?,?)`;
    connection.query(addSql,[username, password],(err)=>{
        if(err){
            res.send(`find err in inserting values, ${err}`);
        }else{
            res.send('insert successfully');
        }
    })
})

成功写入后,会看到insert successfully的提示。

数据的去重

我们存储的是用户的用户名和密码,因此用户名是不能重复的。但是我们可以发送两个同样的数据给后端,会发现不会报错。数据库里面存储了两条一模一样的数据,这是我们不能接受的。

应该如何优化呢?可以试着在数据插入的时候先筛选出和输入的用户名一样的数据,如果已经存在那么便会返回错误。这里就又学到了一个新的SQL语句select param1, param2, ... paramn from TABLE where CONDITION,代表从对应的数据表中选择对应的列。当没有查询到数据的时候,我们需要有一个标志让前端知道我们无法注册用户,这里可以让后端抛出状态码400,以及对应的错误信息。我们这里顺手把其他的错误判断也一并加入。

app.post('/register',(req, res)=>{
    const username = req.body.username;
    let password = req.body.password;
    password = SHA512(password).toString();
    const addSql=`insert into useraccount (username, password) values(?,?)`;
    const selectSql = `select * from useraccount where username = '${username}'`;
    connection.query(selectSql,(err,result)=>{
        console.log(result);
        if(result.length!==0){
            res.status(400).send('用户名已存在');
        }else{
            connection.query(addSql,[username, password],(err)=>{
            if(err){
                res.status(500).send(`注册失败, ${err}`);
            }else{
                res.send('注册成功');
            }
    })
        }
    })
})

现在当你再用同样的用户名post两次后就会出现错误提示了。