Token,Session,Cookie,JWT,Oauth2傻傻分不清楚 2025

Token,Session,Cookie,JWT,Oauth2傻傻分不清楚 2025

    正在检查是否收录...

前言

最近发现有些小伙伴,对Token、Session、Cookie、JWT、OAuth2这些概念非常容易搞混。

有些小伙伴在工作中可能会遇到过这样的困惑:

  • 做登录功能时,到底该用Session还是JWT?
  • OAuth2和Token是什么关系?
  • 为什么有的方案要把Token存在Cookie里?

今天这篇文章专门跟大家一起聊聊这个话题,希望对你会有所帮助。

一、从餐厅就餐模型开始讲

为了让大家更好理解,我先用一个餐厅就餐的比喻来解释这些概念:

image

现在,让我们深入每个概念的技术细节。

二、Cookie:HTTP的世界身份证

2.1 什么是Cookie?

Cookie是

存储在浏览器端的一小段文本数据

,由服务器通过HTTP响应头的Set-Cookie字段发送给浏览器,浏览器随后会自动在每次请求中通过Cookie头将其带回给服务器。

工作原理

image

2.2 Cookie实战代码

// 服务器设置Cookie @PostMapping("/login") public ResponseEntity login(@RequestBody User user, HttpServletResponse response) { if (authService.authenticate(user)) { Cookie cookie = new Cookie("session_id", generateSessionId()); cookie.setMaxAge(3600); // 1小时有效期 cookie.setHttpOnly(true); // 防止XSS攻击 cookie.setSecure(true); // 仅HTTPS传输 cookie.setPath("/"); // 对整个站点有效 response.addCookie(cookie); return ResponseEntity.ok().build(); } return ResponseEntity.status(401).build(); } // 读取Cookie @GetMapping("/profile") public ResponseEntity getProfile(@CookieValue("session_id") String sessionId) { User user = sessionService.getUserBySession(sessionId); return ResponseEntity.ok(user); } 

2.3 Cookie的重要属性

属性 作用 安全建议
HttpOnly 防止JavaScript访问 必须设置为true,防XSS
Secure 仅通过HTTPS传输 生产环境必须设置为true
SameSite 控制跨站请求时是否发送Cookie 建议设置为Strict或Lax
Max-Age 设置Cookie有效期 根据业务安全性要求设置

三、Session:服务端的用户档案

3.1 什么是Session?

Session是

存储在服务器端的用户状态信息

。服务器为每个用户创建一个唯一的Session ID,并通过Cookie将这个ID传递给浏览器,浏览器后续请求时带上这个ID,服务器就能识别用户身份。

Session存储结构

// 典型的Session数据结构 public class UserSession { private String sessionId; private String userId; private String username; private Date loginTime; private Date lastAccessTime; private Map<String, Object> attributes; // 自定义属性 // 省略getter/setter } 

3.2 Session实战代码

// 基于Spring Session的实现 @PostMapping("/login") public String login(@RequestParam String username, @RequestParam String password, HttpSession session) { User user = userService.authenticate(username, password); if (user != null) { // 将用户信息存入Session session.setAttribute("currentUser", user); session.setAttribute("loginTime", new Date()); return "redirect:/dashboard"; } return "login?error=true"; } @GetMapping("/dashboard") public String dashboard(HttpSession session) { // 从Session获取用户信息 User user = (User) session.getAttribute("currentUser"); if (user == null) { return "redirect:/login"; } return "dashboard"; } 

3.3 Session的存储方案

1. 内存存储(默认)

# application.yml server: servlet: session: timeout: 1800 # 30分钟过期时间 

2. Redis分布式存储

@Configuration @EnableRedisHttpSession // 启用Redis Session存储 public class SessionConfig { @Bean public LettuceConnectionFactory connectionFactory() { return new LettuceConnectionFactory(); } } 

3. Session集群同步问题

image

四、Token:去中心化的身份令牌

4.1 什么是Token?

Token是

一种自包含的身份凭证

,服务器不需要在服务端存储会话状态,所有必要信息都包含在Token本身中。

Token vs Session 核心区别


image

4.2 Token实战代码

// 生成Token public String generateToken(User user) { long currentTime = System.currentTimeMillis(); return JWT.create() .withIssuer("myapp") // 签发者 .withSubject(user.getId()) // 用户ID .withClaim("username", user.getUsername()) .withClaim("role", user.getRole()) .withIssuedAt(new Date(currentTime)) // 签发时间 .withExpiresAt(new Date(currentTime + 3600000)) // 过期时间 .sign(Algorithm.HMAC256(secret)); // 签名密钥 } // 验证Token public boolean validateToken(String token) { try { JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secret)) .withIssuer("myapp") .build(); DecodedJWT jwt = verifier.verify(token); return true; } catch (JWTVerificationException exception) { return false; } } 

五、JWT:现代化的Token标准

5.1 什么是JWT?

JWT(JSON Web Token)是

一种开放标准(RFC 7519)

,用于在各方之间安全地传输信息作为JSON对象。

这种信息可以被验证和信任,因为它是数字签名的。

JWT结构

header.payload.signature 

解码示例

// Header { "alg": "HS256", "typ": "JWT" } // Payload { "sub": "1234567890", "name": "John Doe", "iat": 1516239022, "exp": 1516242622 } // Signature HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) 

5.2 JWT实战代码

// 创建JWT public String createJWT(User user) { return Jwts.builder() .setHeaderParam("typ", "JWT") .setSubject(user.getId()) .setIssuer("myapp") .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() + 3600000)) .claim("username", user.getUsername()) .claim("role", user.getRole()) .signWith(SignatureAlgorithm.HS256, secret.getBytes()) .compact(); } // 解析JWT public Claims parseJWT(String jwt) { return Jwts.parser() .setSigningKey(secret.getBytes()) .parseClaimsJws(jwt) .getBody(); } // 在Spring Security中使用JWT @Component public class JwtFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) { String token = resolveToken(request); if (token != null && validateToken(token)) { Authentication auth = getAuthentication(token); SecurityContextHolder.getContext().setAuthentication(auth); } chain.doFilter(request, response); } } 

5.3 JWT的最佳实践

1. 安全存储

// 前端安全存储方案 // 不推荐:localStorage(易受XSS攻击) // 推荐:HttpOnly Cookie(防XSS)或内存存储 

2. 令牌刷新机制

// 双Token机制:Access Token + Refresh Token public class TokenPair { private String accessToken; // 短期有效:1小时 private String refreshToken; // 长期有效:7天 } // 刷新令牌接口 @PostMapping("/refresh") public ResponseEntity refresh(@RequestBody RefreshRequest request) { String refreshToken = request.getRefreshToken(); if (validateRefreshToken(refreshToken)) { String userId = extractUserId(refreshToken); String newAccessToken = generateAccessToken(userId); return ResponseEntity.ok(new TokenPair(newAccessToken, refreshToken)); } return ResponseEntity.status(401).build(); } 

六、OAuth 2.0:授权框架之王

6.1 什么是OAuth 2.0?

OAuth 2.0是

一个授权框架

,允许第三方应用在获得用户授权后,代表用户访问受保护的资源。

OAuth 2.0角色

  • 资源所有者(Resource Owner)

    :用户
  • 客户端(Client)

    :第三方应用
  • 授权服务器(Authorization Server)

    :颁发访问令牌
  • 资源服务器(Resource Server)

    :托管受保护资源

6.2 OAuth 2.0授权码流程

image

6.3 OAuth 2.0实战代码

// Spring Security OAuth2配置 @Configuration @EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("clientapp") .secret(passwordEncoder.encode("123456")) .authorizedGrantTypes("authorization_code", "refresh_token") .scopes("read", "write") .redirectUris("http://localhost:8080/callback"); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) { endpoints.authenticationManager(authenticationManager) .tokenStore(tokenStore()) .accessTokenConverter(accessTokenConverter()); } } // 资源服务器配置 @Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/api/public/**").permitAll() .antMatchers("/api/private/**").authenticated() .antMatchers("/api/admin/**").hasRole("ADMIN"); } } 

七、五大概念对比

为了让大家更清晰地理解这五个概念的关系和区别,我准备了以下对比表格:

7.1 功能定位对比

概念 本质 存储位置 主要用途 特点

Cookie

HTTP状态管理机制 浏览器 维持会话状态 自动携带,有大小限制

Session

服务端会话信息 服务器 存储用户状态 服务端状态,需要存储管理

Token

访问凭证 客户端/服务端 身份认证 自包含,可验证

JWT

Token的一种实现标准 客户端/服务端 安全传输信息 标准化,自包含,可签名

OAuth2

授权框架 不直接存储 第三方授权 标准化授权流程

7.2 应用场景对比

场景 推荐方案 原因说明
传统Web应用 Session + Cookie 简单易用,生态成熟
前后端分离应用 JWT 无状态,适合API认证
第三方登录 OAuth 2.0 标准化授权,安全可靠
微服务架构 JWT 分布式认证,无需会话同步
移动端应用 Token 轻量级,适合移动网络

7.3 安全考虑对比

安全威胁 Cookie方案防护 Token/JWT方案防护
XSS攻击 HttpOnly Cookie 避免localStorage存储
CSRF攻击 SameSite Cookie 自定义Header+CSRF Token
令牌泄露 短期有效+HTTPS 短期有效+HTTPS+刷新机制
数据篡改 服务端验证 签名验证

总结

通过今天的深入探讨,我们可以得出以下结论:

  1. Cookie是载体

    :HTTP协议的状态管理机制,是Session和Token的传输媒介之一。
  2. Session是状态

    :服务端维护的会话状态,需要借助Cookie或URL重写来实现。
  3. Token是凭证

    :认证授权的凭证,可以放在Cookie、Header或URL中。
  4. JWT是标准

    :Token的一种标准化实现,自包含、可验证、可信任。
  5. OAuth2是框架

    :授权框架,定义了完整的第三方授权流程。

最终建议

  • 简单Web应用:Session + Cookie
  • 前后端分离:JWT + HTTP Header
  • 第三方授权:OAuth 2.0 + JWT

没有最好的方案,只有最合适的方案。

理解每个技术的本质和适用场景,才能做出正确的架构决策。

最后说一句(求关注,别白嫖我)

如果这篇文章对您有所帮助,或者有所启发的话,帮忙关注一下我的同名公众号:苏三说技术,您的支持是我坚持写作最大的动力。

求一键三连:点赞、转发、在看。

关注公众号:【苏三说技术】,在公众号中回复:进大厂,可以免费获取我最近整理的10万字的面试宝典,好多小伙伴靠这个宝典拿到了多家大厂的offer。

本文收录于我的技术网站:http://www.susan.net.cn

  • 本文作者:WAP站长网
  • 本文链接: https://wapzz.net/post-27633.html
  • 版权声明:本博客所有文章除特别声明外,均默认采用 CC BY-NC-SA 4.0 许可协议。
本站部分内容来源于网络转载,仅供学习交流使用。如涉及版权问题,请及时联系我们,我们将第一时间处理。
文章很赞!支持一下吧 还没有人为TA充电
为TA充电
还没有人为TA充电
0
0
  • 支付宝打赏
    支付宝扫一扫
  • 微信打赏
    微信扫一扫
感谢支持
文章很赞!支持一下吧
关于作者
2.8W+
9
1
2
WAP站长官方

AI时代,技术人何去何从

上一篇

隐形桌面 AI 助手助力信息管理与知识检索:pickle

下一篇
评论区
内容为空

这一切,似未曾拥有

  • 复制图片
按住ctrl可打开默认菜单