面试官: “ 说一下你对 token 的理解 ? ”

176 阅读3分钟

1. 什么是 Token

Token(令牌)是一串由服务器生成的字符串,用来:

  • 验证用户身份
  • 授权访问资源
  • 防止 CSRF(跨站请求伪造)
  • 管理会话状态

在现代 Web 应用中,Token 通常是无状态的(不依赖服务器保存会话数据),而是由客户端(浏览器、App)存储,并在每次请求时发送给服务器进行验证。


2. Token 的常见类型

(1)JWT(JSON Web Token)

  • 结构:由三部分组成(Header + Payload + Signature),用 . 连接:

    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
    
  • 特点

    • 可包含用户信息(如 userIdrole
    • 可以设置过期时间
    • 服务器端可验证签名,确保未被篡改

(2)Session Token

  • 传统的会话机制:

    • 用户登录后,服务器生成一个唯一的 sessionId
    • sessionId 保存在服务器内存或数据库中
    • 客户端通过 Cookie 保存 sessionId
  • 缺点

    • 服务器需要存储会话状态,不利于分布式部署

(3)OAuth Token

  • 第三方登录授权使用,例如:

    • 微信登录
    • GitHub 登录
    • Google 登录
  • 分为:

    • Access Token:用于访问资源
    • Refresh Token:用于刷新过期的 Access Token

3. Token 的工作流程

以 JWT 为例:

  1. 用户登录用户输入用户名和密码,发送到服务器。

  2. 服务器验证并生成 Token服务器验证成功后,生成一个包含用户信息和过期时间的 JWT。

  3. 客户端存储 Token客户端(浏览器)将 Token 存储在:

    • LocalStorage(跨域需注意安全)
    • SessionStorage(会话结束后失效)
    • Cookie(自动发送,适合有 CSRF 保护的场景)
  4. 客户端发送请求时携带 Token每次请求在 请求头 中添加:

    Authorization: Bearer <token>
    
  5. 服务器验证 Token服务器收到请求后:

    • 检查 Token 是否合法(签名是否正确)
    • 检查 Token 是否过期
    • 根据 Token 中的用户信息授权访问资源

4. Token 的优点

  • 无状态:服务器不需要保存会话数据,便于扩展

  • 跨域支持:可以在不同域之间传递

  • 安全性

    • 可设置过期时间
    • 签名机制防止篡改
    • 相比 Session,减少了服务器存储压力

5. Token 的安全注意事项

  • 不要存储敏感信息:Token 可被解码(虽然不能篡改),不要放密码等敏感数据

  • 使用 HTTPS:防止 Token 在传输过程中被窃取

  • 设置合理的过期时间

    • 短期 Token 减少被盗用风险
    • 配合 Refresh Token 实现无感刷新
  • 防 XSS

    • 如果存储在 LocalStorage,注意防范 XSS 攻击
    • 可以选择 HttpOnly Cookie 存储 Token

6. 示例:使用 JWT

(1)服务器生成 Token(Node.js + jsonwebtoken)

const jwt = require('jsonwebtoken');

// 生成 Token
const token = jwt.sign(
  { userId: 123, username: 'Tom' }, // Payload
  'your-secret-key',                  // 密钥
  { expiresIn: '1h' }                  // 过期时间
);

console.log(token);

(2)客户端存储并发送 Token

// 登录成功后保存 Token
localStorage.setItem('token', token);

// 请求时携带 Token
fetch('https://api.example.com/data', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer ' + localStorage.getItem('token')
  }
});

(3)服务器验证 Token

const jwt = require('jsonwebtoken');

app.get('/data', (req, res) => {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) {
    return res.status(401).json({ msg: '未提供 Token' });
  }

  try {
    const decoded = jwt.verify(token, 'your-secret-key');
    res.json({ user: decoded, data: '敏感数据' });
  } catch (err) {
    res.status(403).json({ msg: 'Token 无效或已过期' });
  }
});

✅ 总结

  • Token 是服务器生成的身份令牌,用于验证用户和授权访问
  • 常见类型:JWTSession TokenOAuth Token
  • 工作流程:登录 → 生成 Token → 客户端存储 → 请求时携带 → 服务器验证
  • 优点:无状态、跨域支持、易扩展
  • 安全:用 HTTPS、设过期时间、防 XSS/CSRF