Node.js零基础入门教程(第4章)-数据库与身份认证

(这是Node.js基础知识的最后一章)


在这里插入图片描述


1. 数据库的基本概念

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
工作表是下面的usersbooks
在这里插入图片描述


2. 安装并配置 MySQL

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


3. MySQL 的基本使用

3.1 使用 MySQL Workbench 管理数据库

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
注意:
填写数据库名称的时候不要带有中文或者空格。如果有空格的话可以选择使用下划线代替。
在这里插入图片描述
AI:自动增长,因为id的值不需要人为操纵,让它自动增长。
在这里插入图片描述

在这里插入图片描述

演示:
我们设置的数据如下
在这里插入图片描述

3.2 使用 SQL 管理数据库

在这里插入图片描述

在这里插入图片描述
我们不用学得很深入,只需要学习里面的增删改查
在这里插入图片描述

3.3 SQL 的 SELECT 语句

在这里插入图片描述
这里的注释符号是--
在这里插入图片描述

在这里插入图片描述
演示:(代码中通过逗号来分隔username和password)
在这里插入图片描述
在这里插入图片描述

3.4 SQL 的 INSERT INTO 语句

在这里插入图片描述

在这里插入图片描述

演示:(插入新数据)
在这里插入图片描述

3.5 SQL 的 UPDATE 的语句

在这里插入图片描述

在这里插入图片描述

演示:(原来是ning,现在更新成xun
在这里插入图片描述

在这里插入图片描述

演示:将第四行的 username 和 password 的数据由原来的(xun, jug)更新成(baolan, sup)
在这里插入图片描述

3.6 SQL 的 DELETE 语句

在这里插入图片描述

在这里插入图片描述

演示:(删除原来 id 为 4 的那行数据)
在这里插入图片描述

3.7 SQL 的 WHERE 子句

在这里插入图片描述
在这里插入图片描述
框起来的部分就是完整的语句,可以被成功执行。where子句则是跟在他们后面代码,是为了代码让更加完整更加好用。

在这里插入图片描述

在这里插入图片描述
演示:
在这里插入图片描述

3.8 SQL 的 AND 和 OR 运算符

在这里插入图片描述

在这里插入图片描述

演示:
在这里插入图片描述

在这里插入图片描述

演示:
在这里插入图片描述

3.9 SQL 的 ORDER BY 子句

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3.10 SQL 的 COUNT(*) 函数

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
演示:
起别名前:
在这里插入图片描述
起别名后:
在这里插入图片描述

如何保存和打开 .sql 文件

保存 .sql 文件:
在这里插入图片描述
打开 .sql 文件:
在这里插入图片描述


4. 在项目中操作 MySQL

4.1 在项目中操作数据库的步骤

在这里插入图片描述

4.2 安装与配置 mysql 模块

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

测试:
在这里插入图片描述

4.3 使用 mysql 模块操作 MySQL 数据库

4.3.1 查询数据

在这里插入图片描述

演示:
代码如下:
在这里插入图片描述
终端结果:
(因为执行的是 select 查询语句,所以查询结果以数组的形式展现)
在这里插入图片描述

4.3.2 插入数据

在这里插入图片描述

演示:
在这里插入图片描述
到数据库里检查:
在这里插入图片描述
说明:
id为4的用户原来是有的,但是我们之前把它删除了。但 id 具有唯一性,只要id被占用过,哪怕数据被删除了,也无法被重新占用。

4.3.3 插入数据的便捷方式

便捷方式的优点在哪里呢?
就是如果数据对象的数据非常多,那我们在db.query的[]中就要全部填写一遍,很繁琐,但是便捷方式可以用一个user代表他们
在这里插入图片描述
演示:
在这里插入图片描述
数据库检查结果:(数据插入成功)
在这里插入图片描述

4.3.4 更新数据

在这里插入图片描述

4.3.5 更新数据的便捷方式

在这里插入图片描述

4.3.6 删除数据

在这里插入图片描述

4.3.7 标记删除

在这里插入图片描述


5. 前后端的身份认证

5.1 Web 开发模式

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

5.2 身份认证

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

5.3 Session 认证机制

在这里插入图片描述

在这里插入图片描述
通过 Cookie 可以突破 HTTP 无状态的限制。
在这里插入图片描述
在这里插入图片描述
Cookie其实就是存储在浏览器中的一段字符串
Cookie是独立的,不同域名下的Cookie不能相互访问。(比如,百度的域名不能访问淘宝的Cookie,同样,淘宝的域名不能访问百度的Cookie)
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
光有会员卡还不行,还得在收银机上刷卡认证,认证成功之后才能被正常使用
在这里插入图片描述
用户信息是存储在服务器中的,而留在浏览器中的是Cookie

5.4 在 Express 中使用 Session 认证

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
req.body即为用户提交到服务器的用户信息。
在这里插入图片描述

在这里插入图片描述
只会清空当前用户的 session,不会清空其他用户的 session

演示 session 案例的效果:

代码如下:

// 导入 express 模块
const express = require('express')
// 创建 express 的服务器实例
const app = express()

// TODO_01:请配置 Session 中间件
// 1. 导入 session 中间件
var session = require('express-session')

// 2. 配置 Session 中间件
app.use(session({
  secret: 'keyboard cat',  // secret 属性的值可以为任意字符串
  resave: false,           // 固定写法
  saveUninitialized: true  // 固定写法
}))

// 托管静态页面
app.use(express.static('./pages'))
// 解析 POST 提交过来的表单数据
app.use(express.urlencoded({ extended: false }))

// 登录的 API 接口
app.post('/api/login', (req, res) => {
  // 判断用户提交的登录信息是否正确
  if (req.body.username !== 'admin' || req.body.password !== '000000') {
    return res.send({ status: 1, msg: '登录失败' })
  }

  // TODO_02:请将登录成功后的用户信息,保存到 Session 中
  // 注意:只有成功配置了 express-session 这个中间件之后,才能通过 req 点出来 session 这个属性
  req.session.user = req.body // 用户的信息
  req.session.islogin = true  // 用户的登录状态

  res.send({ status: 0, msg: '登录成功' })
})

// 获取用户姓名的接口
app.get('/api/username', (req, res) => {
  // TODO_03:请从 Session 中获取用户的名称,响应给客户端
  // 判断用户是否登录
  if(!req.session.islogin) {
    return res.send({status: 1, msg: 'fail'})
  }
  res.send({
    status: 0,
    msg: 'success',
    username: req.session.user.username,
  })
})

// 退出登录的接口
app.post('/api/logout', (req, res) => {
  // TODO_04:清空 Session 信息
  // 调用destroy清空函数
  req.session.destroy()
  res.send({
    status: 0,
    msg: '退出登录成功'
  })
})

// 调用 app.listen 方法,指定端口号并启动web服务器
app.listen(880, function () {
  console.log('Express server running at http://127.0.0.1:880')
})

session 案例的效果演示:
打开网页首先会弹窗提醒登录,登录正确的账号才能跳转进入首页
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.5 JWT 认证机制

在这里插入图片描述
JWT 工作原理的核心就是:服务器生成一个 token,把用户的信息保存在这个token字符串里,然后发送到客户端,今后客户端可以主动将token发送到服务器。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
这段示例中有两个点号,第一个点号前面的是Header区域,第一个点号和第二个点号中间是Payload区域,第二个点号后面的是Signature区域。

在这里插入图片描述

在这里插入图片描述

5.6 在 Express 中使用 JWT

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
expiresIn属性:指定token字符串的有效期,'30s’代表说token从生成那刻起三十秒内是有效的,过了30s这个token就作废了。
在这里插入图片描述
上述.unless....表示,凡是以/api开头的接口都不需要访问权限。
记住 像密码这样的重要信息千万不要加密到token字符串中。
在这里插入图片描述

在这里插入图片描述
代码如下:( JWT 认证机制)

// 导入 express 模块
const express = require('express')

// 创建 express 的服务器实例
const app = express()

// TODO_01:安装并导入 JWT 相关的两个包,分别是 jsonwebtoken 和 express-jwt
const jwt = require('jsonwebtoken')
const expressJWT = require('express-jwt')
// var {expressjwt: jwt} = require('express-jwt')

// 允许跨域资源共享
const cors = require('cors')
app.use(cors())

// 解析 post 表单数据的中间件
const bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({ extended: false }))

// TODO_02:定义 secret 密钥,建议将密钥命名为 secretKey
const secretKey = 'igtheshy 2018'

// TODO_04:注册将 JWT 字符串解析还原成 JSON 对象的中间件
// 使用secretKey密钥对 JWT 字符串进行解密,同时配置 以/api开头的接口都不需要访问权限
// 注意:只要配置成功了 express-jwt 这个中间件,就可以把解析出来的用户信息,挂载到 req.user 属性上
// app.use(expressJWT({secret: secretKey}).unless({ path: [/^\/api\//] })) 
app.use(expressJWT({secret: secretKey, algorithms:['HS256'],}).unless({ path: [/^\/api\//] }))


// 登录接口
app.post('/api/login', function (req, res) {
  // 将 req.body 请求体中的数据,转存为 userinfo 常量
  const userinfo = req.body
  // 登录失败(用户名和密码都必须符合)
  if (userinfo.username !== 'admin' || userinfo.password !== '000000') {
    return res.send({
      status: 400,
      message: '登录失败!'
    })
  }
  // 登录成功
  // TODO_03:在登录成功之后,调用 jwt.sign() 方法生成 JWT 字符串。并通过 token 属性发送给客户端
  // 参数1:用户的信息对象
  // 参数2: 加密的密钥
  // 参数3: 配置对象,可以配置当前 token 的有效期
  const tokenStr = jwt.sign({username: userinfo.username}, secretKey, { expiresIn: '30s'})
  res.send({
    status: 200,
    message: '登录成功!',
    token: tokenStr, // 要发送给客户端的 token 字符串
  })
})

// 这是一个有权限的 API 接口
app.get('/admin/getinfo', function (req, res) {
  // TODO_05:使用 req.user 获取用户信息,并使用 data 属性将用户信息发送给客户端
  console.log(req.user)
  res.send({
    status: 200,
    message: '获取用户信息成功!',
    data: req.user // 要发送给客户端的用户信息
  })
})

// TODO_06:使用全局错误处理中间件,捕获解析 JWT 失败后产生的错误
app.use((err, req, res, next) => {
  // token 解析失败导致的错误(err.name 为UnauthorizedError,说明是解析失败)
  if(err.name === 'UnauthorizedError') {
    return res.send({ status: 401, message: '无效的token'})
  }
  // 其他原因导致的错误
  res.send({ status: 500, message: '未知错误'})
})


// 调用 app.listen 方法,指定端口号并启动web服务器
app.listen(880, function () {
  console.log('Express server running at http://127.0.0.1:880')
})

说明:
POST地址http://127.0.0.1:880/api/login向服务器发送登录请求,成功拿到 token
在这里插入图片描述

新建一个页面,GET地址http://127.0.0.1:880/admin/getinfo,在value值中填入前面拿到的 token,注意我们在代码中设置 token 的有效期只有30s,所以要尽快操作,避免过期。(点击 Send,成功得到反馈信息“获取用户信息成功”)
注意:这里填入 token 的时候要在 token 前面加上 Bearer跟一个空格。这是规定写法
在这里插入图片描述
如果 token 过期,情况会是这样的:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值