1. 数据库

1.1 Node 操作 mysql

1.1.1 配置 mysql 模块

  1. 安装 mysql 模块

    npm install mysql
    
  2. 建立连接

    const mysql = require('mysql')
    const db = mysql.createPool({
      host: '127.0.0.1',
      user: 'root',
      password: 'root',
      database: 'test'
    })
    
  3. 测试是否正常工作

    db.query('select 1', (err, results) => {
      if (err) return console.log(err.message)
      console.log(results)
    })
    

1.1.2 操作 mysql 数据库

  1. 查询数据

    db.query('select * from users', (err, results) => {  ...})
    
  2. 插入数据

    username = "oo1"
    password = "123"
    // ? 表示占位符
    const sql = 'insert into users values(?, ?)'
    // 使用数组的形式为占位符指定具体的值
    db.query(sql, [username, password], (err, results) => {
      if (err) return console.log(err.message)
      if (results.affectedRows === 1)
         console.log('插入成功')
    })
    

    向表中新增数据时,如果数据对象的每个属性和数据表的字段一一对应,则可以通过如下方式快速插入数据:

    const user = {username:'Bruce', password:'55520'}
    const sql = 'insert into users set ? '
    db.query(sql, user, (err, results) => {  ...})
    
  3. 更新数据

    const sql = 'update users set username=?, password=? where id=?'
    db.query(sql, [username, password, id], (err, results) => {  ...})
    

    快捷方式:

    const user = {id:7,username:'Bruce',password:'55520'}
    const sql = 'update users set ? where id=?'
    db.query(sql, [user, user.id], (err, results) => {  ...})
    
  4. 删除数据

    const sql = 'delete from users where id=?'
    db.query(sql, id, (err, results) => {  ...})
    

    使用 delete 语句会真正删除数据,保险起见,使用标记删除的形式,模拟删除的动作。即在表中设置状态字段,标记当前的数据是否被删除。

    db.query('update users set status=1 where id=?', 7, (err, results) => {  ...})
    

1.2 Web 开发模式

1.2.1 服务端渲染

服务器发送给客户端的 HTML 页面,是在服务器通过字符串的拼接动态生成的。因此客户端不需要使用 Ajax 额外请求页面的数据。

app.get('/index.html', (req, res) => {
  const user = { name: 'Bruce', age: 29 }
  const html = `<h1>username:${user.name}, age:${user.age}</h1>`  
	res.send(html)
})

优点:

缺点:

1.2.2 前后端分离

前后端分离的开发模式,依赖于 Ajax 技术的广泛应用。后端只负责提供 API 接口,前端使用 Ajax 调用接口。

优点:

缺点:

1.2.3 如何选择

2. 身份认证

2.1 身份认证

对于服务器渲染和前后端分离这两种开发模式来说,分别有着不同的身份认证方案:

2.1.1 Session 认证机制

服务端渲染推荐使用 Session 认证机制

2.1.2 Session 工作原理

Untitled

2.1.3 Express 中使用 Session 认证

  1. 安装 express-session 中间件

    npm install express-session
    
  2. 配置中间件

    const session = require('express-session')
    app.use(
      session({
        secret: 'Bruce', // secret 的值为任意字符串
        resave: false,
        saveUninitalized: true,
      }))
    
  3. 向 session 中存数据

    中间件配置成功后,可通过 req.session 访问 session 对象,存储用户信息

    app.post('/api/login', (req, res) => {
      req.session.user = req.body
      req.session.isLogin = true
      res.send({ status: 0, msg: 'login done' })
    })
    
  4. 从 session 取数据

    app.get('/api/username', (req, res) => {
      if (!req.session.isLogin) {
        return res.send({ status: 1, msg: 'fail' })
      }
      res.send({ status: 0, msg: 'success', username: req.session.user.username})
    })
    
  5. 清空 session

    app.post('/api/logout', (req, res) => {
      // 清空当前客户端的session信息
      req.session.destroy()
      res.send({ status: 0, msg: 'logout done' })
    })
    

2.2 JWT 认证机制

前后端分离推荐使用 JWT(JSON Web Token)认证机制,是目前最流行的跨域认证解决方案

2.2.1 JWT 工作原理

Session 认证的局限性:

JWT 工作原理图:

用户的信息通过 Token 字符串的形式,保存在客户端浏览器中。服务器通过还原 Token 字符串的形式来认证用户的身份。

Untitled

JWT 组成部分:

Header.Payload.Signature

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTcsInVzZXJuYW1lIjoiQnJ1Y2UiLCJwYXNzd29yZCI6IiIsIm5pY2tuYW1lIjoiaGVsbG8iLCJlbWFpbCI6InNjdXRAcXEuY29tIiwidXNlcl9waWMiOiIiLCJpYXQiOjE2NDE4NjU3MzEsImV4cCI6MTY0MTkwMTczMX0.bmqzAkNSZgD8IZxRGGyVlVwGl7EGMtWitvjGD-a5U5c

JWT 使用方式:

Authorization: Bearer <token>

2.2.2 Express 使用 JWT

  1. 安装
  2. 定义 secret 密钥
  3. 生成 JWT 字符串
  4. JWT 字符串还原为 JSON 对象
  5. 获取用户信息