什么样的登录方式才是最安全的?
目录
一、基础协议:HTTP与HTTPS
HTTP协议
HTTPS协议
二、常见Web攻击与防御
2.1 XSS
常见攻击手段
针对XSS 攻击窃取 Cookie
2.2 CSRF
CSRF攻击的核心特点
与XSS的区别
常见防御措施
三、疑问解答
四、登录方式演变
4.1 方案一🐶狗都不用
介绍
问题
4.2 方案二🐶狗都不用
介绍
问题
4.3 方案三 🐕小狗用一下
问题
总结:
4.4 方案四🐶
普通Token实现
JWT(JSON Web Token)
关键差异对比
使用建议
相交于session机制
需注意的例外情况
在Web开发中,用户认证是保障系统安全的第一道防线。本文将系统性地介绍HTTP/HTTPS、Cookie、Session、Token等核心概念,分析常见攻击手段(XSS/CSRF),并对比不同认证方案的优劣,帮助开发者构建安全的认证体系。
在回答这个问题前,我想先通过几个问题,来建立起登录相关的基本概念,再进行回答。
一、基础协议:HTTP与HTTPS
HTTP协议
- 明文传输:请求和响应报文均为明文形式
- 无状态:每次请求独立,服务器不保留连接信息
- 端口:默认使用80端口
- 风险:易受中间人攻击,敏感信息可能被窃取
HTTPS协议
- 加密传输:在HTTP基础上加入SSL/TLS加密层
- 身份验证:通过CA证书验证服务器真实性
- 端口:默认使用443端口
- 优势:
- 防止数据窃听(传输加密)
- 防止数据篡改(完整性校验)
- 防止身份冒充(证书认证)
虽然HTTPS解决了传输安全问题,但无法防御XSS、CSRF等攻击手段。
二、常见Web攻击与防御
2.1 XSS
XSS(跨站脚本攻击,Cross-Site Scripting)是一种常见的Web安全漏洞,攻击者通过在网页中注入恶意脚本代码,当其他用户访问该页面时,这些脚本会在用户浏览器中执行,从而达到窃取信息或进行其他恶意操作的目的。
常见攻击手段
- 盗取用户Cookie和会话信息
- 伪造用户身份执行操作(如转账、发帖等)
- 植入恶意软件或钓鱼内容
- 发起DDoS攻击
针对XSS 攻击窃取 Cookie
-
攻击方式:黑客注入恶意 JavaScript(如
<script>alert(document.cookie)</script>
),窃取HttpOnly
未设置的 Cookie。 -
防御措施:
-
设置
HttpOnly
属性,禁止 JavaScript 访问 Cookie。 -
启用
Secure
属性,强制 HTTPS 传输。 -
使用
Content-Security-Policy (CSP)
防止 XSS。
-
2.2 CSRF
CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种利用用户已登录状态,诱使用户在不知情的情况下向目标网站发送恶意请求的网络攻击手段。攻击者通过伪造用户请求,冒充用户执行非本意的操作(如转账、修改密码等)。
CSRF攻击的核心特点
- 利用信任机制:依赖网站对用户浏览器的信任(如Cookie/Session认证)
- 无需窃取凭证:攻击者无需获取用户密码或Cookie内容
- 隐蔽性强:攻击过程用户无感知,通常只需点击链接或访问页面
与XSS的区别
特性 | CSRF | XSS |
---|---|---|
攻击目标 | 利用网站对用户的信任 | 利用用户对网站的信任 |
数据获取 | 不直接窃取数据 | 直接窃取Cookie/敏感信息 |
实现方式 | 伪造请求(如<img>标签自动加载) | 注入恶意脚本执行 |
防御重点 | 请求来源验证 | 输入输出过滤 |
常见防御措施
- CSRF Token:服务器生成随机Token,嵌入表单或请求头
<form action="/transfer" method="POST"> <input type="hidden" name="csrf_token" value="a1b2c3d4"> <!-- 其他表单字段 --> </form>
- SameSite Cookie:设置
SameSite=Strict
限制跨站Cookie发送 - 验证Referer:检查请求来源域名是否合法
- 敏感操作二次验证:如短信验证码、密码确认等
根据OWASP统计,CSRF在Web安全威胁中长期位列前十,正确实施Token验证可防范99%的CSRF攻击
三、疑问解答
问题:通过浏览器的控制台能看到当前请求的路径以及输入的账号密码等信息,这些信息难道不会被黑客直接看到吗?
控制台信息需通过物理接触设备或植入恶意脚本才有可能获取,普通网络攻击无法直接利用。
- 通过XSS漏洞注入脚本可窃取控制台数据
- 特定浏览器漏洞可能绕过CSP策略(如Chrome CVE-2020-6519)
- 未启用HTTPS时网络嗅探可获取明文数据
- 恶意WiFi热点可能劫持HTTP连接
那么为什么说cookie和session不一定安全,不都是用https加密了吗
即使使用了 HTTPS 加密传输,Cookie 和 Session 仍然存在安全风险,因为 HTTPS 仅能保护传输过程的相对安全,而无法完全防御其他攻击手段。以下是具体原因分析:
1. HTTPS 的作用与局限
HTTPS(SSL/TLS)主要解决:
-
传输加密:防止数据在传输过程中被窃听(如中间人攻击)。
-
身份验证:确保客户端连接的是真实的服务器(通过 CA 证书)。
但 HTTPS 无法防御以下攻击:
-
XSS(跨站脚本攻击):窃取 Cookie 或 Session ID。
-
CSRF(跨站请求伪造):利用浏览器自动携带 Cookie 的特性发起恶意请求。
-
Session 劫持:通过窃取 Session ID 冒充用户。
-
Cookie 泄露:服务器或客户端存储不当导致泄露。
2. Cookie 的安全风险(即使使用 HTTPS)
(1) XSS 攻击窃取 Cookie
-
攻击方式:黑客注入恶意 JavaScript(如
<script>alert(document.cookie)</script>
),窃取HttpOnly
未设置的 Cookie。 -
防御措施:
-
设置
HttpOnly
属性,禁止 JavaScript 访问 Cookie。 -
启用
Secure
属性,强制 HTTPS 传输。 -
使用
Content-Security-Policy (CSP)
防止 XSS。
-
(2) CSRF 攻击(跨站请求伪造)
-
攻击方式:诱导用户点击恶意链接,浏览器自动携带 Cookie 发起请求(如转账)。
-
防御措施:
-
设置
SameSite
属性(Strict
或Lax
),限制跨站请求。 -
使用 CSRF Token(服务端验证)。
-
(3) Cookie 泄露
-
攻击方式:
-
服务器日志、数据库泄露未加密的 Cookie。
-
客户端存储的 Cookie 被恶意软件读取。
-
-
防御措施:
-
加密敏感 Cookie 数据。
-
定期更换 Session ID。
-
3. Session 的安全风险(即使使用 HTTPS)
(1) Session 劫持(Session Hijacking)
-
攻击方式:
-
通过 XSS 窃取 Session ID。
-
网络嗅探(如公共 Wi-Fi)获取未加密的 Session ID(如果 HTTPS 配置不当)。
-
-
防御措施:
-
绑定 Session 到用户 IP 或 User-Agent(但可能影响用户体验)。
-
使用短 Session 有效期 + 自动注销。
-
(2) Session 固定(Session Fixation)
-
攻击方式:
-
攻击者预先设置 Session ID(如
?PHPSESSID=123
),诱导用户登录后劫持会话。
-
-
防御措施:
-
登录后生成新 Session ID(如
session_regenerate_id()
)。 -
禁用 URL 传递 Session ID。
-
(3) 服务器端 Session 存储泄露
-
攻击方式:
-
服务器文件或数据库被入侵,导致 Session 数据泄露。
-
-
防御措施:
-
加密存储 Session 数据。
-
使用 Redis 等内存数据库,而非文件存储。
-
4. 为什么 JWT 相对更安全?
JWT(JSON Web Token)的安全性依赖于签名机制,但同样需要配合 HTTPS 使用:
-
防篡改:签名确保数据未被修改(如 HMAC 或 RSA)。
-
无状态:服务端无需存储 Session,降低数据库泄露风险。
-
但仍需防范:
-
Token 泄露(XSS 攻击)。
-
弱密钥(如
123456
)。 -
过期时间过长(需设置短
exp
)。
-
四、登录方式演变
问题:
希望页面的相关请求都要维持一个登录状态?怎么做?
换句话说,每次请求都需要知道当前用户是不是登录的状态,怎么实现?
4.1 方案一🐶狗都不用
没有cookie、session、token这些技术
介绍
如果没有cookie、session、token这些技术的话,那么这个问题将会变得非常麻烦。
首先,用户在登录页面,带着用户名密码传递给后端。后端校验通过后,成功响应。
此后,用户再在任何页面发起后端请求时,都要携带这个用户名密码信息,等于说每个接口后端也都需要校验用户名密码。
问题
这样做有什么问题呢?
-
安全性极低 (0%)
每次请求明文传输密码,易被拦截(如中间人攻击),即使使用HTTPS也无法避免密码在客户端存储的风险。
密码长期暴露在请求中,泄露概率大幅增加。
-
性能开销大
每次请求需查询数据库校验密码,高频请求下数据库压力剧增,而Session/Token只需首次登录时校验。
-
用户体验差
用户需手动输入或客户端持久化存储密码,前者操作繁琐,后者不安全。
-
无法实现关键功能
会话管理:无法主动踢人、强制下线或限制并发登录
短期授权:如Token可设置过期时间,而密码无法动态失效
4.2 方案二🐶狗都不用
单cookie。即仅依赖Cookie存储用户信息并维持登录状态。
介绍
Cookie是服务器发送到用户浏览器并保存在本地的一小块数据(通常不超过4KB),会在浏览器下次向同一服务器发起请求时被携带并发送到服务器上。
首先,用户登录时通过用户名密码发起请求,后端校验通过后,通过HTTP响应头中的Set-Cookie字段发送Cookie到客户端(这个cookie记录了用户信息,例如可以是用户名)。
前端收到响应报文后,会将这个cookie保存起来,此后每次请求都携带这个cookie。后端只要能解析到这个cookie。就认为是已登录的。
Cookie的组成
一个完整的Cookie包含以下属性
名称(Name)和值(Value):存储的实际数据
Expires/Max-Age:设置过期时间(不设置则为会话Cookie,关闭浏览器即失效)
Path:定义可访问该Cookie的网站路径
Domain:指定可访问该Cookie的域名
Secure:仅通过HTTPS协议传输
HttpOnly:防止JavaScript访问,增强安全性
Cookie的类型
会话Cookie:临时性,存储在内存中,浏览器关闭后删除
持久Cookie:设置过期时间,存储在硬盘上,在服务器设置的过期时间前一直有效
问题
相较于方案一,每次通过用户名密码,这样的好处仅仅是
-
密码没有明文传递
-
不需要每次手动输入用户名密码
但是问题依旧严重。
-
安全性极低(1%)
若Cookie直接存储用户名、密码或未加密的用户数据,一旦被窃取(如XSS攻击、网络嗅探),攻击者可轻易伪造用户身份
Cookie默认随请求自动发送,攻击者可诱导用户点击恶意链接,利用已登录状态发起伪造请求(如转账操作)
Cookie若未设置
HttpOnly
和Secure
属性,可能被JavaScript读取或通过非HTTPS传输,导致信息泄露。Cooike有容量限制:最大4kb。
相比较方案一:仅仅是没有明文传递,对于正儿八经的的黑客,这没有一点优势,甚至于熟悉cookie攻击的黑客来讲,安全性更差。
-
无法实现关键功能
会话管理:无法主动踢人、强制下线或限制并发登录
短期授权:无法主动使Cookie失效,如用户修改密码后仍需等待Cookie过期,而Session或Token可通过服务端黑名单即时撤销。
-
跨域限制
Cookie默认仅在同域名下发送,难以支持跨域单点登录。
-
客户端依赖
浏览器禁用Cookie时功能完全失效。
4.3 方案三 🐕小狗用一下
采用cookie和session机制。
-
客户端首次请求时,服务器创建Session并生成唯一Session ID。(Session是一种服务器端的会话管理机制,服务器为每个客户端用户创建一个唯一的Session对象来存储会话数据)
-
服务器通过
Set-Cookie
将Session ID发送给客户端(通常名为JSESSIONID或PHPSESSID)Session ID的传递方式:
-
Cookie(最常见方式)
-
URL重写:当Cookie被禁用时,将Session ID附加在URL后
-
隐藏表单字段:通过表单隐藏字段传递
-
-
客户端保存Session ID并在后续请求中携带
-
服务器通过Session ID查找对应的Session数据
注意:整个过程我们只需要往session中存储数据,处理数据即可。其他的像设置cookie这些浏览器就帮我们完成了。
Session的生命周期
创建:用户首次访问时
维护:通过Session ID保持会话状态
销毁:可通过以下方式:
用户主动注销
Session超时(默认通常30分钟)
服务器主动销毁
Cookie与Session的比较
特性 Cookie Session 存储位置 客户端 服务器端 安全性 较低,易被篡改 较高,数据在服务器端 存储容量 有限(约4KB) 无严格限制 生命周期 可长期保存 通常较短 性能影响 几乎无影响 占用服务器资源 数据类型 仅文本 任意类型
问题
-
安全性(⭐⭐)
Cookie安全问题:
-
窃取:需要设置HttpOnly和Secure标志,否则XSS攻击可能获取Cookie
-
伪造:修改客户端Cookie值
-
CSRF攻击:利用用户已认证状态发起恶意请求
Session安全问题:
-
会话劫持:获取有效Session ID
-
会话固定:强制用户使用攻击者提供的Session ID
-
防护措施:
-
使用安全的Session ID生成算法
-
用户登录后更换Session ID
-
设置合理的超时时间
-
-
-
服务器资源消耗
-
session占用服务器内存,用户量大会导致内存压力
-
可能引发内存溢出,特别是Session数据复杂时
-
需要定期清理过期Session,增加服务器负担
-
-
分布式环境问题
-
多服务器环境下需要Session共享机制,处理起来就比较复杂了
-
Session同步可能成为性能瓶颈
-
需要额外配置如Redis等中间件来共享Session
-
-
依赖性问题
-
默认依赖Cookie传递Session ID,当Cookie被禁用时需要URL重写
-
URL重写方式安全性较低且使用不便
-
总结:
虽然这里我标记的两颗星,在应对一些简单的场景时,还是可以用的。但是多集群部署、分布式,甚至高并发场景,对安全性要求更高,那么就不推荐使用了,而且用起来也非常复杂。
4.4 方案四🐶
Token(令牌)
Token是一个广义概念,指任何形式的身份验证令牌,用于在客户端和服务器之间传递身份验证和授权信息。Token可以有多种实现方式,如基于会话的Token、基于时间的Token等。
普通Token实现
通常是一个随机生成的字符串(如UUID),存储在服务器端(如Redis),需要查询验证。
JWT(JSON Web Token)
JWT是一种具体的Token实现方式,遵循RFC 7519标准。它是自包含的,意味着包含了所有必要信息(包括用户信息和签名),无需查询数据库即可验证其有效性。JWT由三部分组成,用点号(.)分隔
-
Header:声明类型和算法(如HS256)
-
Payload:包含声明(用户信息等)
-
Signature:对前两部分的签名,防止篡改
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
说明:
包含关系:JWT是Token的一种特殊形式,所有JWT都是Token,但并非所有Token都是JWT。
信息承载方式:
普通Token:通常只是一个随机字符串,本身不包含信息,需要服务器查询数据库验证。
JWT:自身包含认证信息(JSON格式),通过签名保证完整性,无需服务器存储
验证机制:
普通Token:服务器需要查询数据库验证Token有效性
JWT:服务器直接通过密钥验证签名,无需查询数据库(除非使用黑名单机制)
应用场景
普通Token适用场景:
需要即时撤销Token的情况
对安全性要求极高,需要完全控制Token生命周期的场景
JWT适用场景:
无状态认证(如RESTful API)
跨域认证(如单点登录)
微服务架构中的服务间认证
关键差异对比
特性 | 普通Token | JWT |
---|---|---|
服务器存储 | 需要 | 不需要 |
验证方式 | 查数据库 | 验证签名 |
信息包含 | 无用户信息 | 包含用户信息 |
吊销机制 | 可即时吊销 | 只能等待过期 |
跨域支持 | 有限 | 优秀 |
性能影响 | 数据库I/O开销 | 加密/解密开销 |
适用场景 | 传统Web应用 | 分布式系统/API |
使用建议
-
选择普通Token:当需要即时吊销能力、对安全性要求极高或系统规模较小时
-
选择JWT:在分布式系统、无状态API、前后端分离或需要跨域认证的场景
-
混合使用:某些场景可结合两者优势,如使用JWT作为短期Access Token,配合可吊销的Refresh Token
相交于session机制
Token相比Session在某些方面确实具有更高的安全性。
-
防CSRF攻击能力 Token机制天然免疫CSRF(跨站请求伪造)攻击。
因为Token通常放在HTTP头部的Authorization字段中,而非Cookie,攻击者无法通过伪造链接诱导用户发送携带Token的请求。
而Session依赖Cookie传递Session ID,容易遭受CSRF攻击。
-
无状态架构优势 Token无需服务器存储会话状态,避免了Session面临的会话劫持风险(如Session ID被窃取后可直接冒充用户)。即使Token泄露,也可通过短期有效期和黑名单机制降低风险。
-
分布式场景安全性 在微服务架构中,Token无需Session同步机制,避免了集中式Session存储的单点故障风险。
-
传输安全性 Token可通过HTTPS+加密存储(如HttpOnly Cookie)双重保护,而Session ID默认通过Cookie传输,若未设置Secure标志可能被明文截获。
需注意的例外情况
-
若Token未设置合理过期时间或未加密敏感信息,安全性可能低于严格管理的Session。
-
Session可通过服务端即时吊销(如支付宝退出即销毁Session),而Token需依赖黑名单或等待自然过期。
Token的安全优势主要体现在防篡改、防CSRF和无状态架构设计上,但实际安全性仍取决于具体实现方式(如是否启用HTTPS、签名算法强度等)
在网络安全领域,"没有最安全的方案,只有更安全"这一理念深刻揭示了安全防护的动态本质。