1.0 前言

Session 我们平常开发过程的使用非常频繁,这节我们一起来学习 Session 使用。

2.0 原理讲解

HTTP 是无状态的,因此为了将请求与任何其他请求相关联,您需要一种在 HTTP 请求之间存储用户数据的方法。 Cookie 和 URL 参数都是在客户端和服务器之间传输数据的合适方式。 但是,它们在客户端都是可读的。 Sessions解决了这个问题。 您为客户端分配一个 ID,并使用该 ID 进行所有进一步的请求。 与客户端关联的信息存储在链接到此 ID 的服务器上。

Koa 原生只提供了Cookie 的操作,但是没有提供 Session 的操作,Session 就只用自己实现或者通过第三方中间件实现。

Session 我们可以看成是一个 map,每个用户都有一个 SESSION_ID,Value 包含用户信息,我们先自己实现一个简单的。

  1. // utils/session.js,这里定义 session 基本使用
  2. const {v4: uuidv4 } = require("uuid")
  3. const sessionMap = new Map()
  4. function setSessionInfo(info) {
  5. const uuid = uuidv4()
  6. sessionMap.set(uuid, info)
  7. return uuid
  8. }
  9. function getSeesionInfo(sessionId){
  10. return sessionMap.get(sessionId)
  11. }
  12. function updateSessionInfo(sessionId, info = {}) {
  13. sessionMap.set(sessionId, {...sessionMap.get(sessionId), ...info})
  14. }
  15. module.exports = {
  16. setSessionInfo,
  17. updateSessionInfo,
  18. getSeesionInfo
  19. }

controller/login.js

  1. function getUserInfo() {
  2. // 这里可能是从数据库获取数据,我简单的返回一些信息
  3. return {
  4. userName: "王二码字" + Math.floor(Math.random() * 10)
  5. }
  6. }
  7. function login(ctx) {
  8. const token = '121212-45dfgffgfg'
  9. console.log('ctx.res.header', ctx.response.header)
  10. ctx.response.header.token = token
  11. ctx.app.userInfo = {
  12. name: '王二码字'
  13. }
  14. const uuid = setSessionInfo(getUserInfo())
  15. ctx.cookies.set(
  16. 'SESSION_ID', // key
  17. uuid, // value
  18. {
  19. domain: 'localhost', // 写cookie所在的域名
  20. path: '/', // 写cookie所在的路径
  21. maxAge: 10 * 60 * 1000, // cookie有效时长
  22. expires: new Date('2017-02-15'), // cookie失效时间
  23. httpOnly: false, // 是否只用于http请求中获取
  24. overwrite: false // 是否允许重写
  25. }
  26. )
  27. ctx.redirect('/')
  28. }
  29. module.exports = {
  30. login
  31. }

用户登陆后,在首页我们通过 SESSION_ID 获取用户信息。

  1. // router.js
  2. const {getSeesionInfo} = require('./utils/session')
  3. router.get('/', async (ctx, next) => {
  4. if(!ctx.app.userInfo){
  5. ctx.redirect('/login')
  6. return
  7. }
  8. let title = 'hello koa2'
  9. const userInfo = getSeesionInfo(ctx.cookies.get("SESSION_ID")) // 这里就能通过 SESSION_ID 获取用户信息了
  10. console.log(userInfo)
  11. await ctx.render('index', {
  12. title,
  13. userInfo
  14. })
  15. });

image.png
通过上面代码我们就自己实验了一个基本的 session 功能。

但我们在工作开发中,这种通用的东西一定会有成熟的中间件来使用,接下里我们看看 中间件 koa-session 的使用。

3.0 koa-session

3.0.1 安装

  1. npm install koa-session

3.0.2 基本使用

  1. const session = require('koa-session');
  2. const koa = require('koa');
  3. const app = koa();
  4. app.keys = ['Shh, its a secret!'];
  5. app.use(session(app)); // Include the session middleware
  6. app.use(function *(){
  7. var n = this.session.views || 0;
  8. this.session.views = ++n;
  9. if(n === 1)
  10. this.body = 'Welcome here for the first time!';
  11. else
  12. this.body = "You've visited this page " + n + " times!";
  13. })
  14. app.listen(3000);

上述代码的作用是,当用户访问该站点时,它会为该用户创建一个新会话并分配一个cookie。 下次用户访问时,将检查cookie并相应地更新page_view会话变量。
现在,如果您运行该应用程序并转到localhost:3000,您将收到以下响应。
image.png
如果您再次访问该页面,页面计数器将会增加。 在这种情况下,页面刷新了 8 次。
image.png

koa-session 使用起来还是非常简单了,更多使用细节可以查看 koa-session 文档

4.0 总结

这节我们学习了 什么是 Session ,Session 的原理, 和 koa-session 中间件的使用, Demo 地址