首页 > 其他分享 >一文带你了解Jwt和session的区别

一文带你了解Jwt和session的区别

时间:2024-07-26 23:29:45浏览次数:14  
标签:const 一文 Session JWT Jwt 用户 Token session

全栈开发


文章目录


前言

因为要重构公司的web端产品,和前端一起对了下接口。在对接用户登录的时候,发现当用户关掉浏览器后再次打开浏览器竟然不能无密码登录。然后就和前端商量了下,后端采用jwt技术将生成token给前端,前端将token存储到localstorage,以便后续请求以token方式进行无秘登录以及权限校验。
但是今天在该代码的时候发现后端有用到session进行用户登录的一个校验,似乎和我用的jwt实现的效果有异曲同工之妙,我就好奇了这个和jwt到底有什么区别呢?然后就进行了一番研究…


Session和Jwt是什么?

Session 和 JWT(JSON Web Token) 是两种用于用户身份验证和会话管理的技术,它们各自有不同的特点和应用场景。

Session

概念

Session 是一种服务器端的会话管理技术,用于在用户和服务器之间保持状态信息。Session 通常通过在服务器端存储会话数据来实现。

工作场景

  • 配置

安装需要的库(使用redis作为存储库)。

npm install express-session connect-redis redis

在express中的配置:

const express = require('express');
const session = require('express-session');
const RedisStore = require('connect-redis')(session);
const redisClient = require('redis').createClient();

const app = express();
// 配置 session 中间件
const session_config = {
  store: new RedisStore({ client: redisClient }),
  secret: 'your_secret_key', // 用于加密 session ID 的密钥
  resave: false,             // 是否在每次请求时强制重新保存 session
  saveUninitialized: true,   // 是否在保存 session 前将其初始化
  cookie: { 
    secure: false, // 在 HTTPS 下设置为 true
    maxAge: 3600000 // Cookie 的过期时间(1 小时)
  }
}
app.use(session(session_config));

这样,我们就可以开始在express中使用session了。

  • 用户登录:
    用户提供凭据(如用户名和密码)进行登录。
    服务器验证凭据后,生成一个唯一的 Session ID,并将其存储在服务器端的会话存储中(如内存、文件、数据库或 Redis)。
// 示例路由:用户登录
app.post('/login', (req, res) => {
  const { userId, passWord } = req.body;

  // 在成功登录后存储用户 ID 到会话
  req.session.userId = userId;

  res.send('User logged in');
});

这样我们就把userId作为用户的唯一Session存到redis中了。

  • 发送 Session ID:
    服务器将 Session ID 通过 Set-Cookie 头发送到客户端。浏览器会将这个 Session ID 存储在 Cookie 中。这一步不用我们去做,当我们配置好了中间件express会自动帮我们将 Set-Cookie 头发送到客户端,就是这段代码:
app.use(session(session_config));
  • 后续请求:
    用户在后续的请求中,浏览器会自动将存储的 Session ID Cookie 发送到服务器。服务器使用 Session ID 查找和检索对应的会话数据,以识别用户并处理请求。比如当我们获取用户信息的时候,我们就可以用浏览器发过来的Session ID Cookie找到对应的Session id的数据,进而取出该Session id的在登录时存储的userId,即req.session.userId
// 示例路由:获取用户信息
app.get('/user-info', (req, res) => {
  if (req.session.userId) {
    res.send(`Logged in as user: ${req.session.userId}`);
  } else {
    res.send('No user logged in');
  }
});
  • 关掉浏览器再次打开浏览器无密码登录

上述用户进行登录后,服务器将 Session ID 通过 Set-Cookie 头发送到客户端,用户登录后即使关闭浏览器并重新打开,Cookie 会在客户端保存,保持会话状态。所以当用户再次访问时,浏览器会自动发送保存的 Cookie,服务器能够识别用户并恢复会话。

  • 会话管理:
    服务器可以根据需要更新或销毁会话数据。例如,用户登出时可以删除对应的 Session 数据。
// 示例路由:用户登出
app.post('/logout', (req, res) => {
  req.session.destroy(err => {
    if (err) {
      return res.status(500).send('Failed to destroy session');
    }
    res.send('User logged out');
  });
});

Jwt

概念

JWT 是一种无状态的身份验证机制,它使用 JSON 对象表示的 Token 来进行用户认证和信息交换。JWT 通常用于在客户端和服务器之间安全地传输信息。

工作场景

  • 配置
npm install express  jsonwebtoken
  • 用户登录:

首先用户提供凭据进行登录。服务器验证凭据后,生成一个 JWT。JWT通常包含用户的信息(通常是用户 ID 和其他自定义数据)和签名,用于验证 Token 的完整性,然后返回给前端,前端拿到这个Token并存到localStorage,这样就可以将Token持久化存在浏览器里。

const express = require('express');
const jwt = require('jsonwebtoken');

const app = express();
const secretKey = 'your_secret_key';

app.use(express.json());

app.post('/api/login', (req, res) => {
    const { username, password } = req.body;

    if (username === 'user' && password === 'password') {
        const authToken = jwt.sign({ username }, secretKey, { expiresIn: '1h' });
        res.json({ token: authToken });
    } else {
        res.status(401).json({ message: 'Invalid credentials' });
    }
});
  • 发送 JWT:

服务器将 JWT 发送给客户端,客户端可以将 JWT 存储在 Cookie、localStorage 或 sessionStorage 中。(跟上面最后有点重复)

  • 后续请求:
    用户在后续的请求中,将 JWT 通过请求头(如 Authorization: Bearer )发送到服务器。
    服务器验证 JWT 的签名和有效性,从中提取用户信息,并处理请求。

前端:

const axios = require('axios');

axios.post('/some-protected-route', {}, {
  headers: {
    Authorization: `Bearer ${yourJwtToken}`,
  },
});

后端:

const jwt = require('jsonwebtoken');

// 中间件验证 JWT
const authenticateToken = (req, res, next) => {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1]; // 提取 Bearer Token

  if (token == null) return res.sendStatus(401); // 如果没有 token,返回 401

  jwt.verify(token, 'your_jwt_secret_key', (err, user) => {
    if (err) return res.sendStatus(403); // 如果 token 无效,返回 403
    req.user = user; // 将解码后的用户信息存储在 req 对象中
    next(); // 继续处理请求
  });
};

// 使用中间件
app.use('/some-protected-route', authenticateToken, (req, res) => {
  // 处理受保护的路由
  res.json({ message: 'Access granted', user: req.user });
});
  • 关掉浏览器再次打开浏览器无密码登录
// app.js
import axios from 'axios';
import './axiosConfig'; // 引入配置好的 Axios 拦截器

const checkAuthToken = () => {
  // 从 localStorage 中获取 JWT
  const token = localStorage.getItem('authToken');
  
  if (token) {
    // 如果 JWT 存在,设置 Axios 默认请求头
    axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;

    // 可选:可以发送请求来验证 token 是否仍然有效
    // axios.get('/verify-token')
    //   .then(response => {
    //     // Token 仍然有效,继续执行
    //   })
    //   .catch(error => {
    //     // Token 无效或请求失败,处理逻辑(如清除 token 并引导用户登录)
    //     console.error('Token verification failed', error);
    //     localStorage.removeItem('authToken');
    //     // 可能需要引导用户登录
    //   });
  } else {
    // 如果 JWT 不存在,引导用户登录或显示登录界面
    console.log('No auth token found. Redirecting to login...');
    // 例如,重定向到登录页面
    window.location.href = '/login';
  }
};

// 页面加载时检查 JWT
document.addEventListener('DOMContentLoaded', () => {
  checkAuthToken();
});

  • 无状态:

由于 JWT 是自包含的,服务器不需要存储会话状态,所有必要的信息都包含在 JWT 中。

总结

session

  • 存储位置: 服务器端。

  • 机制: 服务器生成和管理会话 ID,客户端通过 Cookie 发送 Session ID。

  • 优点:
    1.集中管理: Session 数据存储在服务器端,减少了客户端存储的复杂性;
    2.安全性: 由于敏感数据(如用户信息)存储在服务器上,相比于存储在客户端,通常更安全;
    3.易于实现: 很多后端框架和库都原生支持 session,简化了实现过程;
    4.过期管理: Session 过期由服务器控制,不需要客户端进行处理;

  • 缺点:
    1.存储负担: 每个用户的 session 数据都存储在服务器端,可能会消耗大量的服务器内存和存储资源。
    2.跨域问题: 依赖于浏览器的 Cookie 机制,这可能会引发跨域问题,尤其是在多个子域名或不同的应用之间。
    3.负载均衡: 在分布式系统中,多个服务器处理同一应用时,Session 数据的同步和管理可能变得复杂。需要使用外部存储(如 Redis)来解决这个问题。

jwt

  • 存储位置: 客户端。
  • 机制: 服务器生成自包含的 Token,客户端通过请求头发送 Token。
  • 优点:
    1.减少服务器负担: Token 数据存储在客户端,减少了服务器的存储需求。
    2.灵活性: 用户可以在多个设备上使用 Token。
    3.扩展性: Token 机制是无状态的,服务器不需要存储 session 数据,适合分布式系统和微服务架构。
    跨域支持:
    4.方便: Token 不依赖于 Cookie,支持在不同的子域名和跨域场景中使用。
    5.简化认证:无状态认证: 认证信息包含在 Token 中,简化了每次请求的认证流程。
  • 缺点:
    1.安全性问题:客户端存储: 存储在客户端,可能被盗取或篡改。需要额外的措施(如 HTTPS、Token 加密)来保护 Token。
    2.无法失效: Token 一旦生成,在有效期内都有效,无法像 Session 那样容易地失效或撤销。需要实现刷新 Token 机制来处理 Token 过期问题。
    3.复杂性:需要处理 Token 的生成、存储、过期和刷新,可能比 Session 实现要复杂。
    4.数据量大: JWT 可以包含很多信息,可能导致 Token 变得较大,影响性能(特别是在请求头中传递时)。

选择 Session 还是 JWT 取决于具体的应用需求和架构设计。在需要集中管理会话状态的传统应用中,Session 可能是更好的选择;而在分布式系统或微服务架构中,JWT 可能更适合。

标签:const,一文,Session,JWT,Jwt,用户,Token,session
From: https://blog.csdn.net/hola173841439/article/details/140723646

相关文章

  • 什么是Cookie与Session?(一文搞懂)
    在Web开发中,用户状态管理是一个重要的概念。由于HTTP协议的无状态性,每次请求都是独立的,这意味着服务器无法识别连续的请求是否来自同一用户。为了克服这一限制,Cookie和Session应运而生。本文将详细讲解Cookie和Session的概念、工作原理、优缺点以及它们的使用场景,并通过示例帮......
  • jwt令牌生成和解析 + 几种数据获取方法
    ——————jwt令牌生成和解析jdk:17springboot:3.x JwtUtils.java其中StringsingKey这一部分不要太短,不然会报错packagecom.example.utils;importio.jsonwebtoken.Claims;importio.jsonwebtoken.Jwts;importio.jsonwebtoken.SignatureAlgorithm;importjava......
  • 进程和线程的区别到底有哪些,一文带你彻底搞清楚
    进程和线程是现代操作系统中资源管理和任务执行的基本单位。在Linux系统中,进程和线程有着各自的特性和应用场景。理解它们之间的区别,有助于优化应用程序的设计和性能。本文将深入探讨进程和线程的区别,并重点分析它们在Linux系统中的实现和应用。......
  • FlinkSQL窗口函数TUMBLE、SESSION 和 HOP的区别
    目录TUMBLE滚动窗口(TumblingWindow)SESSION会话窗口(SessionWindow)HOP滑动窗口(HoppingWindow)小结HOP窗口为什么不需要rowtime(事件时间) PROCTIME()vsrow_time 为什么HOP窗口常用PROCTIME()?总结TUMBLE、SESSION可以使用处理时间嘛TUMBLE窗口(滚动窗口)SESS......
  • 一文详解 JuiceFS 读性能:预读、预取、缓存、FUSE 和对象存储
    在高性能计算场景中,往往采用全闪存架构和内核态并行文件系统,以满足性能要求。随着数据规模的增加和分布式系统集群规模的增加,全闪存的高成本和内核客户端的运维复杂性成为主要挑战。JuiceFS,是一款全用户态的云原生分布式文件系统,通过分布式缓存大幅提升I/O吞吐量,并使用成本较......
  • 一文教你如何利用ThinkPHP6打造高效SEO优化的网站!
    在今天的互联网时代,网站的SEO(SearchEngineOptimization)优化已经成为了网站建设的一个重要环节。ThinkPHP6是一种基于PHP语言的开源Web应用框架,因其高效、安全、简洁等优势受到广泛的使用和推崇。本文将为大家介绍如何使用ThinkPHP6进行网站SEO优化。一、ThinkPHP6中SEO优化......
  • 一文让你开始使用Anki
    文章目录前言主要界面的几个功能牌组添加浏览统计同步注册账号同步的三种情况正常情况冲突情况新增情况五种基本卡片问答题问答题翻转问答题翻转可选问答题输入答案填空题新增卡片相同卡片其他知识文件工具检查媒体清空卡片笔者的话前言anki我是一直想学习的......
  • 一文彻底搞懂浏览器事件机制、事件委托、事件冒泡、事件循环、Event Loop、react事件
    一、事件是什么?事件模型?事件是用户操作网页时发生的交互动作,比如click/move,事件除了用户触发的动作外,还可以是文档加载,窗口滚动和大小调整。事件被封装成一个event对象,包含了该事件发生时的所有相关信息(event的属性)以及可以对事件进行的操作(event的方法)。事件是用......
  • 【经典问题】精析:一文搞懂 动态规划解决 0-1背包问题
    背包问题核心元素:数量为n的物品,容量为size的背包,给出每个物品的重量weight和价值val,求背包能装的物品最大总价值。求解思路的本质:从小体量(少物品,少容量)的问题开始,不断求出局部最优解,然后以此为基础放大问题(求得较多物品,较大容量下最优解)重复上述过程,直到求出题目要求的最优......
  • 一文看懂llama2(原理&模型&训练)
    关注我,持续分享逻辑思维&管理思维&面试题;可提供大厂面试辅导、及定制化求职/在职/管理/架构辅导;推荐专栏《10天学会使用asp.net编程AI大模型》,目前已完成所有内容。一顿烧烤不到的费用,让人能紧跟时代的浪潮。从普通网站,到公众号、小程序,再到AI大模型网站。干货满满。学成后可......