cookie session token 对比

http 是无状态,也就是说每次的http请求都是独立的。请求和响应无法维护,都是一次性的,
比说 在blog 上留言 发布都需要用户信息的,我们要存储登录用户的状态,
**存储方式**
1.最low 的方法 在window 上挂载用户信息,但是刷新页面 状态就丢失了。
2.放在cookie ,localstorge等里,无论怎么刷新,用户信息都可以持久保留

### cookie

对于前端来说是无感知的,首次请求server返回Set-Cookie:'name=123\&age=333',下次cilent请求自动回带上Cookie 信息
cookie 配置

*   Domain / Path
    Domain 域 限制访问域
    假如server 返回cookie 中携带Domian baidu.com,与当前域名不符,browser 会拒绝存储cookie,反之与当前域名相同 浏览器会存储, server 没有指定Domain 默认存储当前一级域名
    Path 访问路径
    server 返回 path /ace  browser 只有在 /ace/?\* 接口上传输cookie
    path / 所有接口都会传输cookie,前提是域名一致
*   Expires / Max-Age
    Expires UTC 格式 过期时间 为空情况 当浏览器关闭,cookie就会消失,会与本地时间做对比,不是很准确
    Max-Age  从当前时间到过期时间的秒数,时间过期,browser 不在存储cookie,Expires 和Max—Age 同时存在,Max-Age 优先级更高,如果都没有设置,那么cookie 将在会话结束就清空了
*   httponly 不允许client 获取cookie

每次请求都会携带Cookie,这无形中增加了流量开销。
Http请求中Cookie均为明文传输,所以安全性成问题(除非用Https)
Cookie有大小限制,一般最大为4kb。

**cookie 跨源携带**
client 在5500 port
serve 在8000 port
默认情况下,浏览器是不会去为你保存下跨域请求响应的Cookie的。具体现象是:跨域请求的Response响应了即使有Set-Cookie响应头(且有值),浏览器收到后也是不会保存此cookie的。

首先服务端设置cors请求头 并开启Access-Control-Allow-Credentials 允许在跨域情况setCookie
client 设置withCredentials = true 需要在跨域情况存储cookie

注意开启Access-Control-Allow-Credentials,Access-Control-Allow-Origin就不可以设置为\* 了,报错如下。 必须指定host  也就是指定为<http://localhost:5500>

    Access to XMLHttpRequest at 'http://localhost:8000/login' from origin 'http://localhost:5500' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.



    const host = 'http://localhost:5500';
    // 设置请求头
    app.all('*', function (req, res, next) {
      res.setHeader('Access-Control-Allow-Origin', host);
      res.setHeader('Access-Control-Allow-Credentials', true);
      res.setHeader("Content-Type", "application/json;charset=utf-8");
      next();
    });

    document.getElementById('login').onclick = () => {
        var ajax = new XMLHttpRequest();

        //步骤二:设置请求的url参数,参数一是请求的类型,参数二是请求的url,可以带参数
        ajax.open('get', 'http://localhost:8000/login');
        <!--关键 开启withCredentials-->
        ajax.withCredentials = true;
        //步骤三:发送请求
        ajax.send();
        //步骤四:注册事件 onreadystatechange 状态改变就会调用
        ajax.onreadystatechange = function () {
          if (ajax.readyState == 4 && ajax.status == 200) {
            //步骤五 如果能够进到这个判断 说明 数据 完美的回来了,并且请求的页面是存在的
            console.log(ajax.responseText); //输入相应的内容
          }
        };
    };

    这样就可以跨域携带cookie 了

### session

session 一般用在 前后鉴权 登录/验证

*   浏览器登录发送账号密码,服务端查用户库,校验用户
*   服务端把用户登录状态存为 Session,生成一个 sessionId
*   通过登录接口返回,把 sessionId set 到 cookie 上
*   此后浏览器再请求业务接口,sessionId 随 cookie 带上
*   服务端查 sessionId 校验 session
*   成功后正常做业务处理,返回结果

session 存储是一个问题
在内存中存储,用户量级过大,可能导致内存溢出 吃满,如果server 是集群,每次服务器资源都是独立的 不会共享,负载均衡 每次可能会把流量打到不同服务器上,session就会失去作用,解法通过nginx配置 把相同ip流量打到一个服务器上 也可以,通过ip\_hash配置 但是就失去了负载均衡作用
在redis 存储 访问快 而且数据共享,但是内存有限(最优)
在数据坤中存储 空间大,但是访问速度慢

### token

由于session 存储限制,就产生了token,不在服务端存储session了,生成token  后 通过cookie 返回给client 每次请求携带token server 去效验token 信息

**使用token 流程**

*   用户登录,服务端校验账号密码,获得用户信息
*   把用户信息、token 配置编码成 token,通过 cookie set 到浏览器
*   此后用户请求业务接口,通过 cookie 携带 token
*   接口校验 token 有效性,进行正常业务接口处理

token 放在cookie 里传输,明文铁定是不可以的,一般使用base64 加密一下,这也是不安全的。用户a拿到b的uid在转为base64,在修改自己的token,这样不就能登录b的账户了吗
token 设计到敏感操作,所以 需要加密签名sign

#### JWT

JWT是由三段信息构成的,将这三段信息文本用.链接一起就构成了Jwt字符串。
`eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ`

```
header 头部信息
// 加密算法 方式
// {
//  'typ': 'JWT',
//  'alg': 'HS256'
// }
// 在base64 加密 生成下面一坨东西
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9  

中间部分 payload 负载
由自定义信息 (不建议存放敏感信息,因为是对称加密,client是可以解密的)通过base64 加密

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9


signtrue  签证信息

有heaher base64后信息和payload base64后信息加上header内加密方法配合secret (秘钥)加密生成signtrue信息


secret 保存在服务器中, header 和payload 都可以破解,但是没有secret 破解也没有用, secret 用作于jwt 的签发 和jwt 的效验

```

 

posted @ 2022-10-10 15:04  大橙爱吃大橙子  阅读(22)  评论(0编辑  收藏  举报