接口鉴权怎么做?

访客 全栈框架 2

本文目录导读:

  1. 核心思路:三要素
  2. 常见接口鉴权方案(由浅入深)
  3. 实战中的关键决策点
  4. 一个通用的鉴权中间件伪代码(Node.js Express)
  5. 总结建议

接口鉴权(API Authentication)是确保只有合法用户或系统才能访问后端服务的关键环节,具体怎么做取决于你的技术栈、安全要求和应用场景。

下面我为你梳理一套从基础到进阶的实践方案,包含常见实现方式、代码示例和安全建议。

核心思路:三要素

大多数鉴权方案都围绕这三个问题:

  1. 你是谁?(身份识别)
  2. 你带没带凭证?(凭证验证)
  3. 这个凭证是否有效/被篡改?(签名与时效)

常见接口鉴权方案(由浅入深)

HTTP Basic/Digest Auth(极简,不推荐用于生产)

  • 方式:在HTTP Header中直接发送 Authorization: Basic base64(用户名:密码)
  • 优点:实现非常简单。
  • 缺点极度不安全(除非配合HTTPS),密码直接暴露。
  • 适用场景:内部调试、老旧设备的简单对接。

Token 令牌 + Session (有状态)

  • 方式:用户登录 -> 服务端生成Token(如UUID)并存储Session -> 客户端每次请求携带Token -> 服务端查Session校验。

    # Flask 示例
    from flask import Flask, session, request, jsonify
    from uuid import uuid4
    app = Flask(__name__)
    app.secret_key = 'your-secret-key'
    @app.route('/login', methods=['POST'])
    def login():
        # 验证用户名密码...
        session['user_id'] = 123
        session['token'] = str(uuid4())  # 生成Token
        return jsonify({'token': session['token']})
    @app.route('/api/data')
    def api_data():
        # 每次请求校验Token
        token = request.headers.get('Authorization')
        if token != session.get('token'):
            return 'Unauthorized', 401
        return jsonify({'data': 'this is secret data'})
  • 优点:简单,服务端可主动吊销Token。

  • 缺点服务端存储Session有压力,水平扩展困难(需共享Session)。

JWT (JSON Web Token) - 最流行方案

  • 方式:用户登录 -> 服务端签发一个自包含的JWT(包含用户ID、过期时间、签名) -> 客户端请求时带上JWT -> 服务端验签即可(无需查数据库)。

  • 结构Header.Payload.Signature

  • 优点无状态(服务端不需存Token)、跨域友好、支持分布式。

  • 缺点无法主动吊销(除非引入黑名单)、Payload可能被Base64解码(永远不要放密码/敏感信息)。

    // Java (jjwt库) 示例 - 服务端生成JWT
    String jwt = Jwts.builder()
        .setSubject("user123")
        .setIssuedAt(new Date())
        .setExpiration(new Date(System.currentTimeMillis() + 3600_000)) // 1小时过期
        .signWith(SignatureAlgorithm.HS256, "mySecretKey")
        .compact();
    // 客户端请求时在Header中携带
    // Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyMTIzIn0...

OAuth 2.0 / OpenID Connect(第三方授权/开放平台)

  • 方式:授权码模式(Code Flow),用户 -> 第三方应用 -> 授权服务器 -> 资源服务器。
  • 场景:微信登录、Google Login、企业内部SSO。
  • 套路:申请 client_id -> 获取 access_token -> 用 access_token 请求API。
  • 注意OAuth 2.0是授权协议,不是认证协议,需要认证能力(你是谁)要加OpenID Connect。

HMAC (签名算法) / API Key + Secret - 服务间鉴权首选

  • 方式:服务端给客户端分配 AppKeyAppSecret,客户端用 AppSecret 对请求参数+时间戳+随机数进行排序、拼接、加密生成签名 Signature,服务端用同样的 AppSecret 重新计算签名比对。

  • 优点防篡改、防重放、无需传输Secret本身(只传签名)。

  • 场景:开放平台API(如阿里云)、微服务间调用、IoT设备。

    // Node.js 客户端生成签名示例
    const crypto = require('crypto');
    function generateSignature(method, path, params, appSecret) {
        let sortedParams = Object.keys(params).sort().map(key => `${key}=${params[key]}`).join('&');
        let stringToSign = method + '\n' + path + '\n' + sortedParams + '\n' + timestamp;
        return crypto.createHmac('sha256', appSecret).update(stringToSign).digest('hex');
    }
    // 请求时携带: AppKey, Timestamp, Nonce(随机数), Signature
    // 服务端用AppKey查找AppSecret,然后重新计算Signature比对

实战中的关键决策点

  1. 有状态 vs 无状态?

    • 有状态 (Session/Token):方便吊销(比如用户点击“退出登录”,服务器立即删除该Session),适合Web应用、后台系统
    • 无状态 (JWT):性能好,无需分布式Session,适合移动端、微服务,注意:JWT一旦签发,过期前无法主动失效(除非维护黑名单,这又变有状态了)。
  2. 动态鉴权 vs 静态鉴权?

    • 动态:每次请求都校验(JWT验签、HMAC验签),推荐所有对外API使用。
    • 静态:第一次校验后,后续通过IP白名单或内网VPC信任,适合内部微服务间调用。
  3. 防重放攻击

    • 方法1:Nonce + Timestamp(推荐),服务端缓存一段时间内的Nonce(随机数,一次性使用),发现重复则拒绝。
    • 方法2:Timestamp + 时间窗口,请求时间与服务器时间差超过5分钟则拒绝。
  4. 安全传输

    • 绝对必须使用 HTTPS,否则,即使你用了最复杂的鉴权方案,中间人攻击也可以直接拿到你的Token或签名。

一个通用的鉴权中间件伪代码(Node.js Express)

// 鉴权中间件
function authMiddleware(req, res, next) {
  // 1. 放行白名单路径(如 /login, /register, /health)
  if (req.path.startsWith('/public')) return next();
  // 2. 获取Token(从 Header 或 Cookie)
  const token = req.headers['authorization']?.replace('Bearer ', '');
  if (!token) return res.status(401).json({ error: 'Missing token' });
  try {
    // 3. 如果是JWT,直接验签
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded; // 将用户信息放入请求对象
    next();
  } catch (err) {
    // 4. 如果JWT过期或无效,返回401
    if (err.name === 'TokenExpiredError') {
      return res.status(401).json({ error: 'Token expired' });
    }
    return res.status(401).json({ error: 'Invalid token' });
  }
  // 5.(可选)如果是HMAC方案,在这里计算签名并比对
}

总结建议

场景 推荐方案 理由
你的App/Web后台 JWT + HTTPS 无状态、跨平台、简单,配合刷新令牌(Refresh Token)使用。
内部微服务调用 HTTP Basic + HTTPS Service Mesh / mTLS
开放平台/三方API HMAC (API Key + Secret) + 签名 防篡改、防重放,客户端不传输明文Secret。
单点登录(SSO) OAuth 2.0 + OpenID Connect 行业标准,支持多种授权模式(授权码、隐式)。
IoT/低功耗设备 预置证书 + mTLS 或 HTMAC + 动态Token(定期轮换)。

一个关键原则:不要自己造加密轮子。 用成熟的库(如jjwt, pyjwt, express-jwt, oauth2-proxy)和标准算法(SHA-256, RSA, ECDSA)。

标签: 安全认证

抱歉,评论功能暂时关闭!