跨境电商技术架构 亚马逊SP-API API认证 OAuth 2.0

SP-API认证指南

作者: API专家 | 发布于: 2025年3月25日

亚马逊SP-API认证指南

亚马逊Selling Partner API (SP-API)是跨境电商卖家与亚马逊平台集成的核心接口。本文将详细介绍SP-API的认证流程、最佳实践和常见问题解决方案。

SP-API认证概述

SP-API使用OAuth 2.0授权框架,认证流程包括以下几个关键步骤:

  1. 创建IAM用户和角色
  2. 注册应用程序
  3. 获取授权码
  4. 交换访问令牌
  5. 使用访问令牌调用API

详细认证流程

1. 创建IAM用户和角色

首先,需要在AWS IAM控制台创建用户和角色:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "execute-api:Invoke"
      ],
      "Resource": [
        "arn:aws:execute-api:*:*:*"
      ]
    }
  ]
}

2. 注册应用程序

在亚马逊开发者平台注册应用程序,获取以下凭证:

  • Client ID
  • Client Secret
  • AWS IAM ARN

3. 获取授权码

引导卖家完成授权流程,获取授权码:

function generateAuthorizationUrl(clientId: string, state: string): string {
  const params = new URLSearchParams({
    application_id: clientId,
    state: state,
    version: 'beta'
  });
  
  return `https://sellercentral.amazon.com/apps/authorize/consent?${params.toString()}`;
}

4. 交换访问令牌

使用授权码交换访问令牌和刷新令牌:

async function exchangeCodeForTokens(
  authCode: string,
  clientId: string,
  clientSecret: string
): Promise<TokenResponse> {
  const response = await fetch('https://api.amazon.com/auth/o2/token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      code: authCode,
      client_id: clientId,
      client_secret: clientSecret
    })
  });
  
  if (!response.ok) {
    throw new Error(`Token exchange failed: ${response.statusText}`);
  }
  
  return response.json();
}

5. 刷新访问令牌

访问令牌有效期为1小时,需要使用刷新令牌定期更新:

async function refreshAccessToken(
  refreshToken: string,
  clientId: string,
  clientSecret: string
): Promise<TokenResponse> {
  const response = await fetch('https://api.amazon.com/auth/o2/token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: new URLSearchParams({
      grant_type: 'refresh_token',
      refresh_token: refreshToken,
      client_id: clientId,
      client_secret: clientSecret
    })
  });
  
  if (!response.ok) {
    throw new Error(`Token refresh failed: ${response.statusText}`);
  }
  
  return response.json();
}

生成LWA签名

调用SP-API时,需要生成AWS签名V4:

import { SignatureV4 } from '@aws-sdk/signature-v4';
import { Sha256 } from '@aws-crypto/sha256-js';

async function createSignedRequest(
  request: Request,
  region: string,
  accessKey: string,
  secretKey: string,
  sessionToken?: string
): Promise<Request> {
  const signer = new SignatureV4({
    credentials: {
      accessKeyId: accessKey,
      secretAccessKey: secretKey,
      sessionToken
    },
    region,
    service: 'execute-api',
    sha256: Sha256
  });
  
  return signer.sign(request);
}

令牌管理最佳实践

1. 令牌缓存策略

实现高效的令牌缓存机制,避免频繁刷新:

class TokenManager {
  private tokenCache: Map<string, TokenInfo> = new Map();
  
  async getAccessToken(sellerId: string): Promise<string> {
    const cachedToken = this.tokenCache.get(sellerId);
    
    // 检查缓存中的令牌是否有效
    if (cachedToken && cachedToken.expiresAt > Date.now() + 5 * 60 * 1000) {
      return cachedToken.accessToken;
    }
    
    // 刷新令牌
    const tokenResponse = await this.refreshToken(sellerId);
    
    // 更新缓存
    this.tokenCache.set(sellerId, {
      accessToken: tokenResponse.access_token,
      expiresAt: Date.now() + tokenResponse.expires_in * 1000,
      refreshToken: tokenResponse.refresh_token || cachedToken?.refreshToken
    });
    
    return tokenResponse.access_token;
  }
  
  // 其他方法...
}

2. 刷新令牌安全存储

刷新令牌需要安全存储,建议采用以下措施:

  • 使用加密数据库字段
  • 实施最小权限原则
  • 定期审计访问日志

3. 令牌轮换策略

为提高安全性,实施令牌轮换策略:

async function rotateRefreshToken(sellerId: string): Promise<void> {
  // 获取当前刷新令牌
  const currentRefreshToken = await getRefreshToken(sellerId);
  
  // 使用当前刷新令牌获取新的访问令牌和刷新令牌
  const tokenResponse = await refreshAccessToken(
    currentRefreshToken,
    clientId,
    clientSecret
  );
  
  // 如果返回了新的刷新令牌,则更新存储
  if (tokenResponse.refresh_token) {
    await updateRefreshToken(sellerId, tokenResponse.refresh_token);
  }
}

常见问题及解决方案

1. 令牌过期处理

async function executeApiRequest(request: ApiRequest): Promise<ApiResponse> {
  try {
    return await makeApiCall(request);
  } catch (error) {
    if (isTokenExpiredError(error)) {
      // 强制刷新令牌
      await tokenManager.forceRefreshToken(request.sellerId);
      // 重试请求
      return makeApiCall(request);
    }
    throw error;
  }
}

2. 多区域部署策略

SP-API在不同区域有不同的端点,需要正确处理:

const REGION_ENDPOINTS = {
  'NA': 'sellingpartnerapi-na.amazon.com',
  'EU': 'sellingpartnerapi-eu.amazon.com',
  'FE': 'sellingpartnerapi-fe.amazon.com'
};

function getApiEndpoint(region: string): string {
  return REGION_ENDPOINTS[region] || REGION_ENDPOINTS['NA'];
}

3. 错误重试策略

针对不同类型的错误实施不同的重试策略:

async function executeWithRetry(
  fn: () => Promise<any>,
  retryOptions: RetryOptions
): Promise<any> {
  let lastError;
  
  for (let attempt = 0; attempt <= retryOptions.maxRetries; attempt++) {
    try {
      return await fn();
    } catch (error) {
      lastError = error;
      
      // 检查是否应该重试
      if (!shouldRetry(error, attempt, retryOptions)) {
        throw error;
      }
      
      // 计算重试延迟
      const delay = calculateBackoff(attempt, retryOptions);
      
      // 等待后重试
      await sleep(delay);
    }
  }
  
  throw lastError;
}

安全最佳实践

  1. 定期轮换凭证:每90天轮换IAM凭证
  2. 监控异常活动:实施异常检测机制
  3. 最小权限原则:仅请求必要的API权限
  4. 安全审计:定期审查访问日志和权限

结论

SP-API认证是跨境电商系统与亚马逊平台集成的基础。通过正确实施认证流程、采用最佳实践和解决常见问题,可以构建稳定、安全的亚马逊集成解决方案。

在未来的文章中,我们将深入探讨SP-API的具体业务场景应用,如订单管理、库存同步等。

目录

加载中...