目录
一. Token 的英文本义 和 常见令牌
Token
英文本义为“券、信物”,在计算机领域,我们翻译成“令牌”。其实就是“信物”
的意思。我们看影视剧中,主角手握令牌,就可以过城门、进皇宫、领取装备等等。我们在计算机领域中,谁有了有效的 token,谁 就有了临时获取数据的身份,所以 token
翻译成“令牌”,更加的生动。
token 在计算机领域,核心 就是 “available”,我们常见的令牌如下:
-
认证令牌(Authentication Token)
认证令牌是用于验证用户身份的一种机制。当用户登录系统后,服务器端会生成一个唯一的认证令牌,并将其发给用户。用户在随后的请求中附带这个令牌,以此来证明自己的身份。这种机制常用于网络应用,帮助维持用户会话或实现无状态的身份验证。 -
网络令牌(Network Token)
在网络协议中,令牌可以指代控制访问或数据传输的权利。例如,在令牌环网络中,令牌是一个特殊的数据包,只有持有令牌的计算机才能发送数据,从而避免数据碰撞。 -
数字货币和区块链中的Token
在区块链和数字货币领域,Token通常指代在特定区块链上发行的数字资产或代币。这些Token可以代表各种资产,如货币、股份、资产等,且可以在区块链上自由交易。
不同类型的Token在不同的领域和应用场景中扮演着重要角色,但核心都是表示一种可以临时获取数据的身份或资格。我们这里着重的就是讲述的是“认证令牌”。
二. 认证令牌的由来
token 出现前
我们以前设计 登录系统,过程是:
1、客户端通过 用户名和密码登录服务器。
2、服务端收到请求,去验证用户名与密码。验证成功,在当前对话(session)里面保存相关数据,比如用户角色、登录时间等等。
3、服务器向用户返回一个 session_id,写入客户端的 Cookie。
4、客户端随后的每一次请求,都会通过 Cookie,将 session_id 传回服务器。
5、服务器收到 session_id,获取相应的session, 来判断是否通过客户端的请求。
这种验证方式有很多问题,比如,现代系统都是分布式系统,session 无法跨系统共享。
token 出现后
1、客户端使用用户名跟密码请求登录;
2、服务端收到请求,去验证用户名与密码;验证成功,服务端会签发一个Token,然后再把这个 Token 发送给客户端;
3、客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里;
4、客户端每次向服务端请求资源的时候需要带着服务端签发的 Token;
5、服务端收到请求,验证密客户端请求里面带着的 Token, 如果验证成功,就继续执行客户端请求的业务逻辑,否则就是验证失败报错返回给客户端;
三. 基本概念
在 Java 开发中,Token(令牌) 通常指一串经过加密或编码的字符串,作为客户端与服务器之间进行身份验证、信息传递或权限校验的 “凭证”。它本质上是一种轻量级的身份标识,用于替代传统的 Session 机制,尤其在分布式系统、前后端分离架构或跨域场景中广泛使用。
四. Token 的核心作用:
- 身份验证:用户登录成功后,服务器生成一个 Token 并返回给客户端,客户端后续请求时携带该 Token,服务器通过验证 Token 有效性来确认用户身份,无需重复登录。
- 信息传递:Token 可包含少量非敏感用户信息(如用户 ID、角色),减少服务器查询数据库的次数。
- 权限校验:Token 中可嵌入权限信息,服务器通过解析 Token 直接判断用户是否有权限访问某个接口。
- 无状态性:服务器无需存储 Token 相关数据(对比 Session 需要服务器保存会话状态),更适合分布式系统(如微服务架构)。
五. Java 中常见的 Token 场景:
1. JWT(JSON Web Token):
最常用的 Token 格式之一,由三部分组成(头部 Header + 载荷 Payload + 签名 Signature),采用 JSON 格式存储信息,可自包含、可验证。
例如:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkiLCJuYW1lIjoiSm9obiBEb2UifQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
2. OAuth2.0 令牌:
在第三方授权场景中(如微信登录、GitHub 授权),服务器会颁发 Access Token 或 Refresh Token,用于访问第三方资源。
3.自定义令牌:
开发者可自行设计 Token 格式(如 UUID 加盐加密),但安全性和通用性通常不如 JWT。
Java 中处理 Token 的常见方式:
以 JWT 为例,Java 中常用库(如 jjwt、java-jwt)可快速实现 Token 的生成与验证:
/* 引入依赖(Maven)
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<!-- 实现模块(必须包含,否则无具体逻辑) -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<!-- 可选:JSON 处理模块(若用默认序列化需添加) -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
*/
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.security.Key;
import java.util.Date;
public class JwtExample {
// 生成签名密钥(实际开发中需妥善保管,避免泄露)
private static final Key SECRET_KEY = Keys.secretKeyFor(SignatureAlgorithm.HS256);
// Token 过期时间(1小时)
private static final long EXPIRATION_TIME = 3600000;
// 生成 Token
public static String generateToken(String userId, String username) {
return Jwts.builder()
.setSubject(userId) // 主题(通常为用户ID)
.claim("username", username) // 自定义信息
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)) // 过期时间
.signWith(SECRET_KEY) // 签名
.compact();
}
// 验证并解析 Token
public static void validateToken(String token) {
try {
Jwts.parserBuilder()
.setSigningKey(SECRET_KEY)
.build()
.parseClaimsJws(token); // 验证签名和过期时间
System.out.println("Token 有效");
} catch (Exception e) {
System.out.println("Token 无效:" + e.getMessage());
}
}
public static void main(String[] args) {
String token = generateToken("123", "张三");
System.out.println("生成的 Token:" + token);
validateToken(token); // 验证 Token
}
}
六. 优势总结:
- 无状态:服务器无需存储会话信息,减轻分布式系统的同步压力。
- 跨域支持:适合前后端分离(如 Vue/React 前端 + Java 后端)或跨服务调用。
- 扩展性:可灵活嵌入用户信息,减少数据库查询。
在 Java 开发中,Token 是实现身份认证和权限控制的核心手段,尤其在 Spring Security、微服务架构中应用广泛。
题外话:
既然有了令牌,就有了权限、身份。它的作用这么大,那肯定需要防伪,所以令牌 需要 签名 来防伪(或者说认证)。签名的内容点击“这里”