redis/session/jest/jwt

1、redis

1、 redis是内存数据库(mysql是硬盘数据库)
2、下载、安装、使用:
(1)官网下载即可;
(2)启动redis-server、redis-cli连接
3、 nodejs操作redis

/**
 * @description 存储配置
 * @author zrf
 */

let REDIS_CONF = {
    port: 6379,
    host: '127.0.0.1'
};

module.exports = {
    REDIS_CONF
}
/**
 * @description 连接redis的方法 get set
 */

const redis = require('redis');
const { REDIS_CONF } = require('../conf/db');

// 创建客户端
const redisClient = redis.createClient(REDIS_CONF.port, REDIS_CONF.host);
redisClient.on('error', err => {
    console.error(err);
})

/**
 * 
 * @param {string} key 键
 * @param {string} val 值
 * @param {number} timeout 过期时间,单位s
 */
function set(key, val, timeout = 60 * 60) {
    if (typeof val === 'object') {
        val = JSON.stringify(val);
    }
    redisClient.set(key, val);
    redisClient.expire(key, timeout);
}

/**
 * 
 * @param {string} key 
 */
function get(key) {
    const promise = new Promise((resolve, reject) => {
        redisClient.get(key, (err, val) => {
            if (err) {
                reject(err);
                return;
            }
            if (val == null) {
                resolve(null);
                return;
            }
            try {
                resolve(JSON.parse(val));
            } catch (ex) {
                resolve(val);
            }
        })
    })
    return promise;
}

module.exports = {
    set,
    get
}

2、登录(cookie和session)

1、为何session使用用redis存储?
(1)session访问频繁,对性能要求极高
(2)session可不考虑断电丢失数据的问题
(3)session数据量不会太大(相比于mysql中存储的数据)

2、为何网站数据不适合用redis?
(1)操作频率不是太高(相比于session操作)
(2)断电不能丢失,必须保留
(3)数据量太大,内存成本太高

3、koa2配置session

// session配置
app.keys = ['UIsdf_7878#s'];
app.use(session({
  key: 'weibo_sid',  // cookie name
  prefix: 'weibo:sess:', // redis key的前缀
  cookie: {
    path: '/',
    httpOnly: true,
    maxAge: 24 * 60 * 60 * 1000  // 单位ms
  },
  store: redisStore({
    all: `${REDIS_CONF.host}:${REDIS_CONF.port}`
  })
}))

4、jest——单元测试

1、单元测试及其意义
(1)单个功能或接口,给定输入,得到输出。看输出是否符合要求;
(2)需手动编写用例代码,然后统一执行;
(3)意义:能一次性执行所有单测,短时间内验证所有功能是否正常;

2、使用jest
(1)*.test.js文件
(2)常用的断言

/**
 * @description test demo
 */

function sum(a, b) {
    return a + b;
}

test('test demo 1', () => {
    const res = sum(10, 20);
    expect(res).toBe(30);
})

(3)测试http接口

/**
 * @description jest server
 */

const request = require('supertest');
const server = require('../src/app').callback();

module.exports = request(server);

/**
 * @description json test
 */

const server = require("./server")

test('json 接口返回数据格式正确', async () => {
    const res = await server.get('/json');
    expect(res.body).toEqual({
        title: 'koa2 json'
    })
})

5、jwt

(1)jwt——json web token
(2)用户认证成功之后,server端返回一个加密的token给客户端
(3)客户端后续每次请求都带token,以示当前的用户身份

const Koa = require('koa')
const app = new Koa()
// jwt验证
const jwtKoa = require('koa-jwt');

const { SECRET } = require('./conf/constants');

// error han dler
onerror(app)

// jwt验证(客户端请求是否携带了token)
app.use(jwtKoa({
  // secret解密(钥匙)
  secret: SECRET
}).unless({
  // 自定义哪些目录忽略jwt验证
  path: [/^\/users\/login/]
}))
const router = require('koa-router')()
// 加密jsonwebtoken
const jwt = require('jsonwebtoken');
const util = require('util');

const { SECRET } = require('../conf/constants');

const verify = util.promisify(jwt.verify);

router.prefix('/users');
// 登录
router.post('/login', async (ctx, next) => {
  const { username, password } = ctx.request.body;
  let userInfo = null;
  if (username === 'zhangsan' && password === 'abc') {
    userInfo = {
      userId: 1,
      username: 'zhangsan',
      nickname: '张三',
      gender: 1
    }
  }

  // 对用户信息进行加密
  let token = null;
  // 用户认证成功后,返回加密token给客户端
  if (userInfo) {
    token = jwt.sign(userInfo, SECRET, { expiresIn: '1h' });
  }

  if (userInfo == null) {
    ctx.body = {
      code: -1,
      msg: '登录失败'
    }
    return;
  }
  ctx.body = {
    code: 0,
    data: token
  }
})

// 获取用户信息
// 客户端请求携带token,jsonwebtoken解密,返回用户信息
router.get('/getUserInfo', async (ctx, next) => {
  const token = ctx.request.header.authorization;
  try {
    const payload = await verify(token.split(' ')[1], SECRET);
    ctx.body = {
      code: 0,
      userInfo: payload
    }
  } catch (err) {
    ctx.body = {
      code: -1,
      errmsg: err.message
    }
  }
})
module.exports = router

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值