会话控制与本地存储

9 篇文章 0 订阅
8 篇文章 0 订阅

会话控制

http请求是无状态的,无法区分多次的请求是否来自同一个客户端。

cookie

概念

1.最大存储4k
2.携带在每个http请求中,增加了流量
3.cookie是明文传输
4.对于浏览器外的其他客户端,如安卓、ios需要手动设置cookie和session
5.对于分布式系统和服务器集群中如何保证其他系统也可以正确解析session
在这里插入图片描述

express中使用cookie

cookie相关api

// 1.设置内存cookie 关闭浏览器时清除
res.cookie("name")
// 设置硬盘cookie 关闭浏览器不清除,到过期时间清除
res.cookie("name", "ccc", { maxAge: 60 * 1000 });

// 2.获取cookie
req.cookies

// 3.删除cookie
res.clearCookie("name");

koa中使用cookie

cookie相关api

// 1.设置内存cookie 关闭浏览器时清除
ctx.cookies.set(name, value, [options])
ctx.cookies.set('username', 'ccc', {
  httpOnly: true,
  maxAge: 86400000, // 一天
});

// 2.获取cookie
ctx.cookies.get(name, [options])

// 3.删除cookie
ctx.cookies.set('username', null, {
  maxAge: 0, // 或者使用 expires 选项将过期时间设置为过去的时间戳
  httpOnly: true,
});

session

概念

session和cookie类似,也是存储用户信息。不同是的是session存储在服务器,cookie存储在浏览器。
在这里插入图片描述

express中使用session

session相关api

req.session.username='张三'; //设置session 
req.session.username //获取session 
req.signedCookies.username //获取加密的cookie
req.session.cookie.maxAge=0; //重新设置cookie的过期时间,它会销毁所有的session
req.session.destroy(function(err) { /*销毁 session*/ })
req.session.username = "" //销毁指定的session
const express = require("express");
const router = express.Router();
const session = require("express-session");
const MongoStore = require("connect-mongo");
const md5 = require("md5");

// 使用express-session中间件
router.use(
  session({
    name: "sid", // session对应的cookie名称 默认为connect.sid
    secret: "cjc", // 加盐
    saveUninitialized: false, // 强制保存未初始化的session
    resave: true, // 强制重新保存session,即使没有变化
    store: MongoStore.create({
      mongoUrl: "mongodb://127.0.0.1:27017/testDatabase",
    }), // 数据库连接配置,在testDatabase下自动创建session集合
    cookie: {
      httpOnly: true, // 前端无法操作该cookie
      maxAge: 1000 * 60, // cookie过期时间(故也是sessionID过期时间)
    },
  })
);

router.post("/register", express.json(), (req, res) => {
  const { name, pwd } = req.body;
  if (req.session.name === name) {
    res.end(`${name}已注册`);
  }
  // 设置session,中间件自动将数据保存到数据库
  req.session.name = name;
  req.session.pwd = md5(pwd);
  res.end(`${name}注册成功`);
});

router.post("/login", express.json(), (req, res) => {
  const { name, pwd } = req.body;
  if (md5(pwd) === req.session.pwd && name === req.session.name) {
    req.session.name = name;
    req.session.pwd = pwd;
    res.end(`${name}登录成功`);
  } else {
    res.end("账号或密码错误");
  }
});

router.post("/logout", express.json(), (req, res) => {
  req.session.destroy((err) => {
    if (err) {
      res.end("cannot access session here");
    }
    res.end("退出成功");
  });
});

module.exports = router;

koa中使用session

在这里插入图片描述

token

生成token:登录时,颁发token令牌
验证token:访问某些资源时,验证token

JWT

JWT(JSON Web Token)实现token机制:
在这里插入图片描述
HS256算法为对称加密,但不是所有服务器都需要颁发token的能力。当secretKey暴露存在安全隐患

koa使用token

npm i jsonwebtoken
const Koa = require('koa')
const KoaRouter = require('@koa/router')

const app = new Koa()
const jwt = require('jsonwebtoken')

const testRouter = new KoaRouter({ prefix: "/test" })

// 秘钥
const secretKey = '666'
testRouter.post('/register', (ctx, next) => {
  // 颁发token
  const payload = {name:'ccc',age:999}
  const token = jwt.sign(payload,secretKey,{
    expiresIn: 60
  })

  ctx.body = {
    code: 200,
    meg:'登录成功',
    token
  }
})

testRouter.get('/other', (ctx, next) => {
  // 获取客户端携带过来的token
  const authorization = ctx.header.authorization
  console.log('authorization: ',authorization);
  const token = authorization.replace('Bearer ','')
  
  try {
    // 验证token  
    const res = jwt.verify(token,secretKey)
    ctx.body = {
      res,
      meg:'other页面'
    }
  } catch (error) {
    ctx.body = {
      msg: '无效token'
    }    
  }
})

app.use(testRouter.routes())
app.use(testRouter.allowedMethods())

app.listen(8888, 'localhost', () => {
  console.log(`http://localhost:8888`);
})

在header中携带token:
在这里插入图片描述
无效token:
在这里插入图片描述

非对称加密

私钥:颁发token令牌
公钥:验证tokrn令牌
1.在git-bash中使用openssl生成公钥秘钥文件

openssl
genrsa -out private.key 1024
rsa -in private.key -pubout -out public.key

2.使用公钥、秘钥

// 私钥
const privateKey = fs.readFileSync('./key/private.key')
// 公钥
const publicKey = fs.readFileSync('./key/public.key')

// 颁发token
const payload = {name:'ccc',age:999}
const token = jwt.sign(payload,privateKey,{
  expiresIn: 60,
  algorithm: 'RS256'
})

// 验证token  
const res = jwt.verify(token,publicKey,{
  algorithms:['RS256']
})

本地存储

localStorage与sessionStorage

localStorage 单个Item 最大5M

sessionStorage 单个Item 最大5M

Storage.length  // 表示存储本地存储对象的个数
Storage.setItem('key','value')
Storage.getItem('key')
Storage.removeItem('key')
Storage.clear()
  • localStorage与sessionStorage的API一致。
  • localStorage会永久存储,除非手动删除
  • sessionStorage关闭窗口重新打开会被删除
  • sessionStorage在页面内跳转会被保留 a标签的target=‘_self
  • sessionStorage在页面外跳转会被删除 a标签的target=‘_blank

存储值为对象形式

// 保存数据
localStorage.setItem('obj1',JSON.stringify(obj))

// 获取数据
JSON.parse( localStorage.getItem('obj1') )

IndexedDB

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值