偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Token,Session,Cookie,Jwt,Oauth2傻傻分不清楚

開發(fā) 前端
Cookie是存儲在瀏覽器端的一小段文本數(shù)據(jù),由服務(wù)器通過HTTP響應(yīng)頭的Set-Cookie字段發(fā)送給瀏覽器,瀏覽器隨后會自動在每次請求中通過Cookie頭將其帶回給服務(wù)器。

前言

最近發(fā)現(xiàn)有些小伙伴,對Token、Session、Cookie、JWT、OAuth2這些概念非常容易搞混。

有些小伙伴在工作中可能會遇到過這樣的困惑:

  • 做登錄功能時,到底該用Session還是JWT?
  • OAuth2和Token是什么關(guān)系?
  • 為什么有的方案要把Token存在Cookie里?

今天這篇文章專門跟大家一起聊聊這個話題,希望對你會有所幫助。

一、從餐廳就餐模型開始講

為了讓大家更好理解,我先用一個餐廳就餐的比喻來解釋這些概念:

圖片圖片

現(xiàn)在,讓我們深入每個概念的技術(shù)細(xì)節(jié)。

二、Cookie:HTTP的世界身份證

2.1 什么是Cookie?

Cookie是存儲在瀏覽器端的一小段文本數(shù)據(jù),由服務(wù)器通過HTTP響應(yīng)頭的Set-Cookie字段發(fā)送給瀏覽器,瀏覽器隨后會自動在每次請求中通過Cookie頭將其帶回給服務(wù)器。

工作原理

圖片圖片

2.2 Cookie實戰(zhàn)代碼

// 服務(wù)器設(shè)置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訪問

必須設(shè)置為true,防XSS

Secure

僅通過HTTPS傳輸

生產(chǎn)環(huán)境必須設(shè)置為true

SameSite

控制跨站請求時是否發(fā)送Cookie

建議設(shè)置為Strict或Lax

Max-Age

設(shè)置Cookie有效期

根據(jù)業(yè)務(wù)安全性要求設(shè)置

三、Session:服務(wù)端的用戶檔案

3.1 什么是Session?

Session是存儲在服務(wù)器端的用戶狀態(tài)信息。服務(wù)器為每個用戶創(chuàng)建一個唯一的Session ID,并通過Cookie將這個ID傳遞給瀏覽器,瀏覽器后續(xù)請求時帶上這個ID,服務(wù)器就能識別用戶身份。

Session存儲結(jié)構(gòu)

// 典型的Session數(shù)據(jù)結(jié)構(gòu)
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實戰(zhàn)代碼

// 基于Spring Session的實現(xiàn)
@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. 內(nèi)存存儲(默認(rèn))

# 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集群同步問題

圖片圖片

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

4.1 什么是Token?

Token是一種自包含的身份憑證,服務(wù)器不需要在服務(wù)端存儲會話狀態(tài),所有必要信息都包含在Token本身中。

Token vs Session 核心區(qū)別

圖片圖片

4.2 Token實戰(zhàn)代碼

// 生成Token
public String generateToken(User user) {
    long currentTime = System.currentTimeMillis();
    return JWT.create()
            .withIssuer("myapp") // 簽發(fā)者
            .withSubject(user.getId()) // 用戶ID
            .withClaim("username", user.getUsername())
            .withClaim("role", user.getRole())
            .withIssuedAt(new Date(currentTime)) // 簽發(fā)時間
            .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);
        returntrue;
    } catch (JWTVerificationException exception) {
        returnfalse;
    }
}

五、JWT:現(xiàn)代化的Token標(biāo)準(zhǔn)

5.1 什么是JWT?

JWT(JSON Web Token)是一種開放標(biāo)準(zhǔn)(RFC 7519),用于在各方之間安全地傳輸信息作為JSON對象。

這種信息可以被驗證和信任,因為它是數(shù)字簽名的。

JWT結(jié)構(gòu)

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實戰(zhàn)代碼

// 創(chuàng)建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
publicclass 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)或內(nèi)存存儲

2. 令牌刷新機制

// 雙Token機制:Access Token + Refresh Token
publicclass 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:授權(quán)框架之王

6.1 什么是OAuth 2.0?

OAuth 2.0是一個授權(quán)框架,允許第三方應(yīng)用在獲得用戶授權(quán)后,代表用戶訪問受保護(hù)的資源。

OAuth 2.0角色

  • 資源所有者(Resource Owner):用戶
  • 客戶端(Client):第三方應(yīng)用
  • 授權(quán)服務(wù)器(Authorization Server):頒發(fā)訪問令牌
  • 資源服務(wù)器(Resource Server):托管受保護(hù)資源

6.2 OAuth 2.0授權(quán)碼流程

圖片圖片

6.3 OAuth 2.0實戰(zhàn)代碼

// Spring Security OAuth2配置
@Configuration
@EnableAuthorizationServer
publicclass 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());
    }
}

// 資源服務(wù)器配置
@Configuration
@EnableResourceServer
publicclass 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");
    }
}

七、五大概念對比

為了讓大家更清晰地理解這五個概念的關(guān)系和區(qū)別,我準(zhǔn)備了以下對比表格:

7.1 功能定位對比

概念

本質(zhì)

存儲位置

主要用途

特點

Cookie

HTTP狀態(tài)管理機制

瀏覽器

維持會話狀態(tài)

自動攜帶,有大小限制

Session

服務(wù)端會話信息

服務(wù)器

存儲用戶狀態(tài)

服務(wù)端狀態(tài),需要存儲管理

Token

訪問憑證

客戶端/服務(wù)端

身份認(rèn)證

自包含,可驗證

JWT

Token的一種實現(xiàn)標(biāo)準(zhǔn)

客戶端/服務(wù)端

安全傳輸信息

標(biāo)準(zhǔn)化,自包含,可簽名

OAuth2

授權(quán)框架

不直接存儲

第三方授權(quán)

標(biāo)準(zhǔn)化授權(quán)流程

7.2 應(yīng)用場景對比

場景

推薦方案

原因說明

傳統(tǒng)Web應(yīng)用

Session + Cookie

簡單易用,生態(tài)成熟

前后端分離應(yīng)用

JWT

無狀態(tài),適合API認(rèn)證

第三方登錄

OAuth 2.0

標(biāo)準(zhǔn)化授權(quán),安全可靠

微服務(wù)架構(gòu)

JWT

分布式認(rèn)證,無需會話同步

移動端應(yīng)用

Token

輕量級,適合移動網(wǎng)絡(luò)

7.3 安全考慮對比

安全威脅

Cookie方案防護(hù)

Token/JWT方案防護(hù)

XSS攻擊

HttpOnly Cookie

避免localStorage存儲

CSRF攻擊

SameSite Cookie

自定義Header+CSRF Token

令牌泄露

短期有效+HTTPS

短期有效+HTTPS+刷新機制

數(shù)據(jù)篡改

服務(wù)端驗證

簽名驗證

總結(jié)

通過今天的深入探討,我們可以得出以下結(jié)論:

  1. Cookie是載體:HTTP協(xié)議的狀態(tài)管理機制,是Session和Token的傳輸媒介之一。
  2. Session是狀態(tài):服務(wù)端維護(hù)的會話狀態(tài),需要借助Cookie或URL重寫來實現(xiàn)。
  3. Token是憑證:認(rèn)證授權(quán)的憑證,可以放在Cookie、Header或URL中。
  4. JWT是標(biāo)準(zhǔn):Token的一種標(biāo)準(zhǔn)化實現(xiàn),自包含、可驗證、可信任。
  5. OAuth2是框架:授權(quán)框架,定義了完整的第三方授權(quán)流程。

最終建議

  • 簡單Web應(yīng)用:Session + Cookie
  • 前后端分離:JWT + HTTP Header
  • 第三方授權(quán):OAuth 2.0 + JWT

沒有最好的方案,只有最合適的方案。

理解每個技術(shù)的本質(zhì)和適用場景,才能做出正確的架構(gòu)決策。

責(zé)任編輯:武曉燕 來源: 蘇三說技術(shù)
相關(guān)推薦

2021-08-02 12:50:45

sessiontokenJava

2021-03-10 08:56:37

Zookeeper

2021-03-23 10:45:23

CookieSession前端

2024-02-29 09:08:56

Encoding算法加密

2021-07-27 07:31:16

JavaArrayList數(shù)組

2022-05-15 21:52:04

typeTypeScriptinterface

2018-12-17 12:30:05

Kubernetes存儲存儲卷

2020-10-30 08:20:04

SD卡TF卡存儲

2023-09-03 21:18:07

Python編程語言

2018-05-22 16:24:20

HashMapJavaJDK

2020-03-03 17:35:09

Full GCMinor

2023-02-27 15:46:19

數(shù)據(jù)元元數(shù)據(jù)

2025-08-18 03:25:00

2024-11-04 00:00:03

viewportDOMSPA

2016-11-04 12:51:46

Unix網(wǎng)絡(luò)IO 模型

2021-11-09 06:01:35

前端JITAOT

2022-02-25 09:14:33

類變量共享實例變量

2021-02-08 23:47:51

文件存儲塊存儲對象存儲

2025-05-12 08:40:00

前端監(jiān)控DOM

2025-08-14 08:21:17

PODAODTO
點贊
收藏

51CTO技術(shù)棧公眾號