session-based 与 token-based 的验证,有什么不同?

2025年8月5日

💎 加入 E+ 成長計畫 與超過 700+ 位工程師一同在社群成長,並獲得更多深度的軟體前後端學習資源

谈到软体应用程式开发,就免不了谈登入 (验证) 这个主题。所谓的验证 (authentication) 做的事情是验证你的身分,白话来说就是让系统知道你是你,而不是别人。在登入时输入帐号密码,即是一种验证你确实是你的方式 (假设在安全的状况下,只有你知道你的帐号密码,所以可以借此验证)。

授权  (authorization) 则是涉及你有什么权限。在系统确认你确实是你后,系统会需要进一步判断你有什么权限,并基于你有的权限,开放让你能做不同的操作。

在这篇文章,我们主要会讨论前者,谈不同角度切入的验证模式,不会谈及「验证成功后,这位使用者有哪些权限可以做哪些事」。

此外,中文常会把 verification 也翻译成验证,但在写这篇文章前查证过,繁体中文圈目前对 authentication 的翻译多数都选用「验证」,包含 Google 或 Microsoft 的技术文件翻译都选这个词。所以文章中提到「验证」都是指 authentication 而不是 verification。

󠀠

什么是 session-based 验证?

session-based 如下图所示,这种验证方式最基本的运作,是使用者第一次登入时,伺服器端会生一个对应的 session,然后会有相关的 session ID,并且会透过 HTTP 的 Set-Cookie 在浏览器的 cookie 中存下这个 session ID。

session-based

在这之后,因为发送请求时,浏览器会自动带上这个 cookie,所以使用者就不需用每次进到画面,就必须重新输入帐号密码,省下许多麻烦。

󠀠

session-based 的验证机制,有更多其他潜在的问题。其中一个对后端来说比较麻烦的问题,是随着网页应用的市场发展逐渐成熟,单一的伺服器变得不足以应付逐渐变大的流量;于是越来越多透过水平扩展 (horizontal scaling) 的方式,用多台伺服器来处理来自使用者的请求。

󠀠

这时问题就来了,因为 session 是由单一伺服器管理的,如果有多台伺服器,就会有 session 要如何处理的问题。一个做法是确保同一个使用者的请求都进到同个伺服器 (俗称 sticky session 的做法),或是像用额外的存储机制来处理(俗称 session store 的做法), 每次要验证时就先去跟那个中央存储机制拿,但这两种做法都会让整体系统的复杂度变高。

󠀠

除此之外,两个做法都会有潜在的单点故障问题 (single point of failure),因为把同使用者的请求都送到同台伺服器上,如果该伺服器挂了,那使用者的请求别台伺服器没办法处理;如果用 session store 这种做法,可能会用 Redis,假如 Redis 挂了,那这样其他伺服器就没办法处理同一个 session。

token-based 验证机制

前面的段落提到 session-based 的验证是由 cookie 中带上 session ID,然后由伺服器端透过 session ID 去处理验证。而 token-based 的验证方式,则是以 token 做为辨识使用者的方式。

󠀠

具体来说,客户端会在登入后,拿到 token,然后再后续的请求,都会戴上 token,而伺服器端验证 token 即可,因此使用者不用每次都得输入帐号密码来验证。

󠀠

这两种验证方式最主要的区别在于是否有「状态」,在 sesison-based 的验证方式下,伺服器端会维持 session 的状态,也因为这个特性,导致前面提到的扩展时的问题 。而 token-based 的验证方式,则不需用额外维持状态,而是直接透过 token 来进行验证即可。

󠀠

重点差异在于状态维持

上面谈到「session-based 的验证是由 cookie 中带上 session ID,然后由伺服器端透过 session ID 去处理验证」,很多读者可能会问「但我看 token-based 验证」在

没错,即使是 token-based 的验证方式,也推荐要把 token 存在 cookie 当中,这点我们在《如何设计前端登入机制? 该用 localStorage 还是 cookie 保持登入状态?》有详细谈。

换句话说 session-based 是把 session ID 放 cookie,token-based 是把 token 放 cookie,不是说用 token-based 就不用 cookie。以 ChatGPT 网页版来说,就是把 token 放 cookie 来做验证的例子 (开浏览器开发者工具来看就会看到)。

所以这边区分两种验证方式的关键,还是在状态维持与否 (stateful 或 stateless)。当然,纯粹的无状态验证,也会有问题,所以业界后来才延伸出 access token 搭配 refresh token 这种混合模式。

进一步说,谈到透过 token 验证,相信多数人在碰到这个主题时,或多或少因为各类 token ( bearer token、ID token、access token、refresh token、transparent token、opaque token),觉得眼花撩乱。

󠀠

我们在 E+ 成长计划的主题文,有详细地谈了这些不同 token,分别的作用,以及彼此的关系。如果有兴趣更深入理解,欢迎加入 E+ 成长计划 (连结)

🧵 如果你想收到最即時的內容更新,可以在 FacebookInstagram 上追蹤我們