@commercelayer/js-auth

中文文档
8.1.0发布于 2026/11/02MITTypeScriptESM + CJS零依赖构建来源已验证近 30 天下载 3.1万

一个JavaScript库,旨在与商务地层API互动时简化认证.

中文使用文档
文档目录21 节
  1. 什么是商业层?
  2. 目录
  3. 开始
  4. 安装
  5. API 证书
  6. 储存战略
  7. 销售渠道
  8. 一体化
  9. 其他流动
  10. 有授权代码流的 Webapp 应用程序
  11. 规定适用
  12. 客户证书流程
  13. 公用事业
  14. 撤销一个符号
  15. 解码访问符
  16. 正在验证访问符
  17. 获取核心 API 基准终点
  18. 获取提供 API 基端点
  19. 贡献者指南
  20. 需要帮忙吗?
  21. 许可证

商业层

轻量级 JavaScript 库,旨在简化 认证 当与商业层 API 交互时。 它提供了一种坚固的箱外缓存系统,支持可配置的持续存储、复合存储策略和专用的客户令牌管理.

它在任何地方都有作用——在你的浏览器,服务器上,或者在边缘.

什么是商业层?

商业层 是一个多市场商业API和订单管理系统,它允许您在任何网站,移动应用程序,聊天机,可穿戴,语音,或IoT设备中加入全局购物能力,轻松地. 用你已经掌握和热爱的最好的工具来整理你的堆叠. 通过一个快速的 企业级的 安全的API.

目录


开始

要开始商业层 JS Auth 你需要安装它 并添加到您的项目中.

NPM JSR Lightway     Discord

安装

商业层 Auth 作为 npm 软件包可用 .

# npm
npm install @commercelayer/js-auth

# yarn
yarn add @commercelayer/js-auth

# pnpm
pnpm add @commercelayer/js-auth

# deno
deno add jsr:@commercelayer/js-auth

# bun
bun add @commercelayer/js-auth

API 证书

商业层执行工业标准 OAuth 2.0 数据 管理客户授权的协议。 它定义了不同类型的API证书. 哪一个要使用取决于你的具体需要.

[注] 检查我们 API 证书文件 了解如何通过商业层仪表板创建这些证书.

要使用商务层 API,您首先需要获得授权 。 这意味着你需要获得有效的访问符.

flowchart TB
  %% Default style for nodes
  classDef node stroke-width:2px;

  %% Main nodes
  auth("<b>Auth API</b><br/><br/>https://<b>auth</b>.commercelayer.io")

  dashboard("JWT Dashboard")
  user("JWT User")
  sales_channel("JWT Sales Channel")
  integration("JWT Integration")
  webapp("JWT WebApp")

  provisioningAPI("<b>Provisioning API</b><br/><br/>https://<b>provisioning</b>.commercelayer.io")
  coreAPI("<b>Core API</b><br/><br/>https://#lt;<b>slug</b>#gt;.commercelayer.io")
  metricsAPI("<b>Metrics API</b><br/><br/>https://#lt;<b>slug</b>#gt;.commercelayer.io/metrics")
  comingSoon("<b>Metrics API</b> (coming soon)<br/><br/>https://<b>metrics</b>.commercelayer.io")

  %% Node styles
  style dashboard fill:#FFE6CC,stroke:#D79B00,color:#000
  style user fill:#F8CECC,stroke:#B85450,color:#000
  style sales_channel fill:#D5E8D4,stroke:#82B366,color:#000
  style integration fill:#DAE8FC,stroke:#6C8EBF,color:#000
  style webapp fill:#E1D5E7,stroke:#9673A6,color:#000
  style comingSoon opacity:.3

  %% Connections
  auth --> dashboard
  auth --> user
  auth --> sales_channel
  auth --> integration
  auth --> webapp

  dashboard --> provisioningAPI
  user --> provisioningAPI
  user --> comingSoon
  sales_channel --> coreAPI
  integration --> coreAPI
  integration --> metricsAPI
  webapp --> coreAPI
  webapp --> metricsAPI

  %% Arrow Styles
  linkStyle default stroke-width:2px;
  linkStyle 5 stroke:#D79B00
  linkStyle 6 stroke:#B85450
  linkStyle 7 stroke:#B85450,stroke-dasharray: 5 5,opacity:.3
  linkStyle 8 stroke:#82B366
  linkStyle 9 stroke:#6C8EBF
  linkStyle 10 stroke:#6C8EBF
  linkStyle 11 stroke:#9673A6
  linkStyle 12 stroke:#9673A6

认证呼叫必须服从 费率限制。为了避免击中这些限制,您应当将认证符缓存到存储器中(如cookie,Redis,KV等). 这无法为每次API呼叫请求新令牌 .

这个库提供了一个强大的符号缓存系统出箱,支持您选择的任何存储解决方案. 它包括用于编组多存储机制(如内存+Redis)的工具来减少基础配置存储上的负载,并提供专门的客户符管理.

[注] 对于高级使用时需要直接控制符管理的情况,可以绕过内置缓存辅助器(makeSalesChannel 财务报告和审定财务报表 makeIntegration和 使用该 authenticate 直接方法。 。 。 .

储存战略

  • 单一存储 ——提供能活过页面再装入的临时或持续存储. 您可以执行任何存储解决方案 .
  • 复合储存 -使用 createCompositeStorage 帮助器,可以结合多个存储机制(例如内存+Redis)来优化性能并减少基础所配置存储上的负载.
  • 客户存储 (单位:千美元)仅销售渠道)——可选客户认证信使专用存储,与来宾信使分离.

下面的示例显示带有内存的基本设置 :

import {
  makeSalesChannel,
  type Storage,
  type StorageValue,
} from "@commercelayer/js-auth"

/**
 * A valid storage must implement the `Storage` interface
 */
function memoryStorage(): Storage {
  const store = new Map<string, StorageValue>()
  return {
    name: "in-memory",
    async getItem(key) {
      return store.get(key) ?? null
    },
    async setItem(key: string, value: StorageValue) {
      store.set(key, value)
    },
    async removeItem(key: string) {
      store.delete(key)
    },
  }
}

const salesChannel = makeSalesChannel(
  {
    clientId: "<your_client_id>",
    scope: "market:code:europe",
    debug: {
      logLevel: "info"
    },
  },
  {
    storage: memoryStorage(),
  },
)

/**
 * At the beginning, you'll get a guest token
 */
const authorization1 = await salesChannel.getAuthorization()

console.log("Guest access token:", authorization1.accessToken)

/**
 * For consecutive calls, you'll get the previous guest token
 * from the storage or a new one if expired
 */
const authorization2 = await salesChannel.getAuthorization()

console.log("Customer access token:", authorization2.accessToken)

授权使用来自客户身份和范围的密钥存储,其中 type 是授权类型( y)guest 或者说 customer:

cl_${type}-${clientId}-${scope}

如果您需要不同的密钥( 例如自定义前缀, 或额外的标识符), 您可以自行提供 getKey 函数 :

const salesChannel = makeSalesChannel(
  {
    clientId: "<your_client_id>",
    scope: "market:code:europe"
  },
  {
    storage: memoryStorage(),
    getKey: async ({ clientId, scope }, type) =>
      `myprefix_${type}-${clientId}-${scope}`,
  },
)

以下流程图说明了库如何管理符号缓存、验证和刷新流程:

flowchart TB
  %% Default style for nodes
  classDef node stroke-width:2px,color:#000;

  GetAuthorization(".getAuthorization()") --> CheckCustomerStorage{"Check <b>Customer</b><br/>in storage"}

  CheckCustomerStorage -->|Found| ValidateCustomerToken{"Is token<br/>still valid?"}
  CheckCustomerStorage -->|Not Found| CheckGuestStorage{"Check <b>Guest</b><br/>in storage"}

  ValidateCustomerToken -->|Yes| ReturnCustomerToken(["Return <b>Customer</b> Token"])
  ValidateCustomerToken -->|No| HasRefreshToken{"<b>Customer</b> has<br/>refresh token?"}

  HasRefreshToken -->|Yes| RefreshToken["Refresh <b>Customer</b> token"]
  HasRefreshToken -->|No| CheckGuestStorage

  RefreshToken --> StoreNewToken["Store new <b>Customer</b> token"]
  StoreNewToken --> ReturnCustomerToken

  %% CheckGuestMemory -->|Found| ValidateGuestToken{"Is token<br/>still valid?"}
  %% CheckGuestMemory -->|Not Found| CheckGuestStorage{"Check <b>Guest</b><br/>in storage"}

  ValidateGuestToken -->|Yes| ReturnGuestToken(["Return <b>Guest</b> token"])
  ValidateGuestToken -->|No| CreateNewGuest["Create new <b>Guest</b> token"]

  CheckGuestStorage -->|Found| ValidateGuestToken{"Is token<br/>still valid?"}
  CheckGuestStorage -->|Not Found| CreateNewGuest

  CreateNewGuest --> StoreNewGuestToken["Store new <b>Guest</b> token"]
  StoreNewGuestToken --> ReturnGuestToken

  classDef process fill:#DAE8FC,stroke:#6C8EBF
  classDef condition fill:#FFE6CC,stroke:#D79B00
  classDef code fill:#FFF,stroke:#000,font-family:monospace
  classDef startState fill:#FFF,stroke:#000
  classDef endState fill:#FFF,stroke:#000

  class GetAuthorization code;
  class Start startState;
  class CheckCustomerMemory,CheckCustomerStorage,CheckGuestMemory,CheckGuestStorage condition;
  class ValidateCustomerToken,ValidateGuestToken,HasRefreshToken condition;
  class RefreshToken,StoreCustomerTokenInMemory,CreateNewGuest,StoreNewToken,StoreNewGuestToken process;
  class ReturnCustomerToken,ReturnGuestToken endState;

客户存储

销售渠道处理两种标志: 来宾 符号,与任何身份无关,可以安全分享,以及 客户 这是私人恩怨 可选 customerStorage 选项允许您将客户代号与来宾代号分开存储。 客户代币是否保持被隔离,取决于两件事:它们被写入的存储,以及它们被存储在下面的密钥.

在浏览器中,一切都在外出工作:存储(例如. localStorage)已标注为单一访客.

[尖叫声] 默认密钥是 没有 包括任何客户身份。 如果客户代币被缓存在默认密钥下由所有访客共享的存储中(例如Redis或服务器上的内映映射),则一个客户代币将送达 每个 来客.

在服务器上安全存储客户代币有两种方式:

  1. 使用每个访客 customerStorage。 。 。 . 当客户存储被设定为访问者范围(如cookie)时,默认密钥是完美无缺的,因为存储本身属于单一访问者. 这对自然与服务器侧制成的店面对齐,其中单一的来宾符可以被缓存服务器侧并被所有访客共享:

    const salesChannel = makeSalesChannel(
      {
        clientId: "<your_client_id>",
        scope: "market:code:europe"
      },
      {
        // The guest token carries no identity:
        // one token, cached server-side, serves all visitors...
        storage: memoryStorage(),
        // ...while the customer token is personal
        // and lives in a per-visitor storage (e.g. cookies).
        customerStorage: cookieStorageAdapter,
      },
    )
    
  2. 使用自定义密钥共享存储 . 如果您宁愿在共享服务器侧存储器中缓存客户签名( 例如 Redis), 请使用 getKey 函数可以在密钥中包含客户端或会话标识符。 自兹 getKey 仅接收客户身份、范围和授权类型,必须通过关闭获取请求上下文。 创建每个请求的助手, 同时保留存储后端 :

    import {
      createCompositeStorage,
      makeSalesChannel,
    } from "@commercelayer/js-auth"
    
    // Shared, process-level storage (this is where tokens are actually cached).
    const sharedStorage = createCompositeStorage({
      name: "bff",
      storages: [memoryStorage(), redisStorage],
    })
    
    // Per-request helper: creating it is cheap (no network calls, no timers).
    function salesChannelFor(customerId: string) {
      return makeSalesChannel(
        {
          clientId: "<your_client_id>",
          scope: "market:code:europe"
        },
        {
          storage: sharedStorage,
          getKey: async ({ clientId, scope }, type) =>
            type === "customer"
              ? `cl_customer-${clientId}-${scope}-${customerId}`
              : `cl_guest-${clientId}-${scope}`,
        },
      )
    }
    

[注] 帮手们回来了 makeSalesChannel 财务报告和审定财务报表 makeIntegration 轻量级工厂:它们自己没有象征性的状态(在配置的仓库里住着),在施工时没有I/O。 只要存储后端是共享的,每个请求创建一个是安全的. 唯一长寿的例子就是飞行中同时分解 getAuthorization() 打电话.

调试和存储名称

您可以启用调试, 并为您的存储实例指定自定义名称, 以便更好的可见度 :

  • debug - 接受一个 DebugConfig 有两个选项的对象:
    • logLevel: "info" ——只记录有意义的事件:缓存丢失,令牌刷新,授权存储/撤销,以及出错. 常规缓存点击是沉默的,所以设置调用 getAuthorization() 每一次API请求都不要淹没日志.
    • logLevel: "verbose" ——还记录稳态操作(每个存储读取和缓存被击中).
    • maskToken ——是否在日志输出中掩盖访问符并刷新符(例如. eyJh...A9Xz) (中文(简体) ). 默认为 true设置为 false 以查看完整的代号,例如用于在 jwt.io (英语)。 。 。 .
    • logger ——每个条目的写法. 无论是 "console" (默认)或诸如 jsonLogger。见 将日志转发到日志采集器。 。 。 .
  • name ——您存储实例的自定义标识符,在使用多个存储或复合存储配置时有用. 这个 name 是存储本身的一个属性(如 memoryStorage 以上实例) (中文(简体) ).

这个 createCompositeStorage 帮助者接受自己的 debug 选项,遵循同样的规则:对第一个(快速)存储的命中状态是稳定的,而返回较慢存储则是值得记录的有意义的事件.

[尖叫声] 何时 maskToken 设置为 false完全进入信号 和刷新信号 登录到控制台。 仅用于本地开发——在无服务器/对接环境中,可以将日志传输到外部日志汇总服务.

 const salesChannel = makeSalesChannel(
   {
     clientId: "<your_client_id>",
     scope: "market:code:europe",
+    debug: {
+      logLevel: "info"
+    },
   },
   {
     storage: {
+      name: "storage-name",
+      debug: {
+        logLevel: "info"
+      },
       async getItem(key) {
         // implementation
       },
       // ...
     }
   },
 )

使用未储存

这个 Storage 接口与 unstorage 图书馆。 不过, unstorage 不包括一个 name 默认财产。 为启用调试并识别日志中使用的存储, 将 createStorage 使用此助手 :

import type { Storage } from "@commercelayer/js-auth"
import type { CreateStorageOptions } from "unstorage"
import { createStorage as unstorageCreateStorage } from "unstorage"

// Helper to create storage with explicit naming support
function createStorage(
  options: CreateStorageOptions & { name?: string },
): Storage {
  return {
    name: options.name ?? options.driver?.name,
    ...unstorageCreateStorage(options),
  }
}
// Usage example
import redisDriver from "unstorage/drivers/redis"

const redisStorage = createStorage({
  name: "redis-persistent",
  driver: redisDriver({
    url: "<your_redis_connection_string>",
  }),
})

当调试被启用时,日志会包含存储名,从而更容易追踪哪个存储层正在处理每个操作.

将日志转发到日志采集器

默认( E)logger: "console")每个条目均用 console.log(message, ...data),因此对象可以在浏览器devtools中保持可扩展并可以在终端中读取. 在Node.js,虽然, console.log 打印整个对象 多行,以及读取 stdout (Datadog, Cloud Watch, Google Cloud Looking, Loki,.) 的日志收集器将其中每一行作为单独的日志条目来摄取.

logger 也接受接收每个条目的函数。 这个 jsonLogger 帮助器是一个这样的功能:它每个条目写一个单行的JSON对象. 你可以选择每个环境:

import { jsonLogger, makeSalesChannel } from "@commercelayer/js-auth"

const salesChannel = makeSalesChannel({
  clientId: "<your_client_id>",
  scope: "<your_scope>",
  debug: {
    logLevel: "info",
    logger: process.env.NODE_ENV === "production" ? jsonLogger : "console",
  },
})
{"name":"@commercelayer/js-auth","level":"info","source":"sales_channel","storageName":"memory","message":"Stored \"customer\" authorization to storage","data":[{"accessToken":"eyJh...A9Xz","scope":"market:all"}]}

Error 数值扩展为 { name, message, stack, cause } 加上任何自定义属性,包含自身对象被替换为 "[Circular]"所以伐木从不扔.

要将条目传送到您自己的日志机( pino, winston,...), 请通过您自己的功能 :

import pino from "pino"

const log = pino()

const salesChannel = makeSalesChannel({
  clientId: "<your_client_id>",
  scope: "<your_scope>",
  debug: {
    logLevel: "info",
    logger: ({ level, message, ...entry }) => {
      log[level === "verbose" ? "debug" : "info"](entry, message)
    },
  },
})

在登录器到达之前, 使用托肯口罩, 所以 maskToken 跟每个伐木工一起工作 一个日志函数所抛出的错误会被忽略,所以一个失败的日志永远不会中断认证.

销售渠道

销售渠道 用于构建任何客户触点(例如,您的商店前端带有一个功能完备的购物车和取出流程).

以下是一个完整的例子

import { authenticate, makeSalesChannel } from "@commercelayer/js-auth"

// The `Storage` interface is fully-compatible with the `unstorage` library.
import { createStorage } from "unstorage"
import localStorageDriver from "unstorage/drivers/localstorage"

const salesChannel = makeSalesChannel(
  {
    clientId: "<your_client_id>",
    scope: "market:code:europe",
  },
  {
    /**
     * You can use any storage implementation you prefer or implement your own.
     * In this example we use `unstorage` with the `localStorage` driver
     */
    storage: createStorage({
      driver: localStorageDriver({}),
    }),
  },
)

/**
 * Get the current authorization state which includes the access token.
 * This method handles caching and token refresh automatically.
 */
const guestAuthorization = await salesChannel.getAuthorization()

console.log("Guest access token:", guestAuthorization.accessToken)

/**
 * Authenticate a customer using their email and password, or
 * though the JWT bearer flow.
 */
const customerCredentials = await authenticate("password", {
  clientId: "<your_client_id>",
  scope: "market:code:europe",
  username: "[email protected]",
  password: "secret",
})

/**
 * Set the customer credentials in the storage.
 */
await salesChannel.setCustomer({
  accessToken: customerCredentials.accessToken,
  scope: customerCredentials.scope,

  /**
   * When `refreshToken` is provided, it'll be used to automatically
   * refresh the customer access token when it expires.
   */
  refreshToken: customerCredentials.refreshToken,
})

/**
 * Get the current customer authorization.
 */
const customerAuthorization = await salesChannel.getAuthorization()

console.log("Customer access token:", customerAuthorization.accessToken)

/**
 * Logout the current customer.
 * This will remove the customer authorization from the storage, and revoke the access token.
 */
await salesChannel.logoutCustomer()

/**
 * You can also clear stored authorizations without revoking the tokens,
 * e.g. to force a fresh authorization on the next `getAuthorization()` call.
 */
await salesChannel.removeAuthorization("all") // or "customer" / "guest"

客户认证通过两个OAuth 2.0赠款类型得到支持: 密码 财务报告和审定财务报表 JWT 无记名者。两种流动返回 accessToken, (中文(简体) ), scope,以及 refreshToken 可使用 setCustomer 方法.

基于密码的客户认证

销售渠道可以使用 密码 用于交换客户证书的赠款类型,以获取访问令牌(即获取"登录"访问令牌).

import { authenticate } from "@commercelayer/js-auth"

const auth = await authenticate("password", {
  clientId: "<your_client_id>",
  scope: "market:code:europe",
  username: "[email protected]",
  password: "secret"
})

console.log("My access token:", auth.accessToken)
console.log("Expiration date:", auth.expires)
console.log("My refresh token:", auth.refreshToken)

销售渠道可以使用 刷新符号 用“ 记住我” 选项刷新客户访问符的赠款类型 :

import { authenticate } from "@commercelayer/js-auth"

const newToken = await authenticate("refresh_token", {
  clientId: "<your_client_id>",
  scope: "market:code:europe",
  refreshToken: "<your_refresh_token>"
})

[注] 使用时 makeSalesChannel 帮助者, 自动处理符号刷新 。 帮助器监视符过期后无缝地刷新了背景中的客户符,消除了手动刷新呼叫的需要.

JWT 无记名认证

商业层支持 OAuth 2. 0 JWT 缓冲器 通过交换JWT断言,使应用程序能够获取访问令. 这对于执行授权认证流程特别有用,因为应用程序需要代表客户发出API呼叫,而不需要其直接互动. 流动包括两个步骤:

  1. 开具附有客户索赔的JWT签名断言

    import { createAssertion } from "@commercelayer/js-auth"
    
    const assertion = await createAssertion({
      payload: {
        "https://commercelayer.io/claims": {
          owner: {
            type: "Customer",
            id: "4tepftJsT2"
          },
          custom_claim: {
            customer: {
              first_name: "John",
              last_name: "Doe"
            }
          }
        }
      }
    })
    
  2. 将此断言交换为访问符

    import { authenticate } from "@commercelayer/js-auth"
    
    const auth = await authenticate("urn:ietf:params:oauth:grant-type:jwt-bearer", {
      clientId: "<your_client_id>",
      clientSecret: "<your_client_secret>",
      scope: "market:code:europe",
      assertion
    })
    
    console.log("My access token:", auth.accessToken)
    console.log("Expiration date:", auth.expires)
    console.log("My refresh token:", auth.refreshToken)
    

销售渠道和网络app都可以使用JWT无记名流执行安全授权认证.

来自外部身份提供者的授权登录

当客户通过外部身份提供商(如:Okta, Auth0)认证时,您的后端可以使用JWT无记名流量交换其身份来换取商业层客户代币,并将其交给 salesChannel 帮助器( 由于此流运行服务器侧, 请参见 客户存储 适合设置的章节 :

import {
  authenticate,
  createAssertion,
} from "@commercelayer/js-auth"

// 1. Validate the external identity (e.g. verify the IdP-issued JWT)
//    and resolve it to a Commerce Layer customer ID.
const customerId = await resolveCustomerId(idpToken)

// 2. Create the signed assertion and exchange it for a customer token.
//    This step requires the client secret, so it must run server-side.
const assertion = await createAssertion({
  payload: {
    "https://commercelayer.io/claims": {
      owner: {
        type: "Customer",
        id: customerId
      },
    },
  },
})

const customerCredentials = await authenticate("urn:ietf:params:oauth:grant-type:jwt-bearer", {
  clientId: "<your_client_id>",
  clientSecret: "<your_client_secret>",
  scope: "market:code:europe",
  assertion,
})

// 3. Hand the customer token over to the `salesChannel` helper
//    created with `makeSalesChannel`.
//    From now on, `getAuthorization()` returns the customer authorization
//    and refreshes it automatically when it expires.
await salesChannel.setCustomer({
  accessToken: customerCredentials.accessToken,
  scope: customerCredentials.scope,
  refreshToken: customerCredentials.refreshToken,
})

一体化

一体化 用于开发与任何三党制的后端集成.

import {
  createCompositeStorage,
  makeIntegration,
} from "@commercelayer/js-auth"

// The `Storage` interface is fully-compatible with the `unstorage` library.
import { createStorage } from "unstorage"
import memoryDriver from "unstorage/drivers/memory"
import redisDriver from "unstorage/drivers/redis"

const memoryStorage = createStorage({
  driver: memoryDriver(),
})

const redisStorage = createStorage({
  driver: redisDriver({
    url: "<your_redis_connection_string>",
  }),
})

const compositeStorage = createCompositeStorage({
  name: "composite-storage",
  storages: [
    memoryStorage,
    redisStorage,
  ]
})

const integration = makeIntegration(
  {
    clientId: "<your_client_id>",
    clientSecret: "<your_client_secret>",
    debug: {
      logLevel: "info"
    },
  },
  {
    storage: compositeStorage,
  },
)

/**
 * If you already requested an access token before, now you'll probably get it from Redis if not expired.
 * Otherwise, a new one will be requested.
 * 
 * This method handles caching and token refresh automatically.
 */
const authorization1 = await integration.getAuthorization()

console.log("Integration access token #1:", authorization1.accessToken)

/**
 * Subsequent calls will return the cached token from memory storage.
 */
const authorization2 = await integration.getAuthorization()

console.log("Integration access token #2:", authorization2.accessToken)

/**
 * Revoke the current integration authorization.
 * This will remove the authorization from memory and storage, and revoke the access token.
 */
await integration.revokeAuthorization()

/**
 * Disposes all mounted storages to ensure there are no open-handles left.
 * Call it before exiting process.
 */
await compositeStorage.dispose?.()

其他流动

有授权代码流的 Webapp 应用程序

仅供浏览器应用程序使用

网络应用程序使用 授权代码 授权类型以交换访问符的授权代码.

步骤

在此情况下,首先需要获得授权代码,然后用访问符交换:

  1. 创建商务层上的网络应用程序,并注意API证书(客户ID,客户端秘密,召回 URL,基端点,以及您想要设置范围的市场ID)

  2. 使用此 URL 授权您在商业层上的网络应用 :

https://dashboard.commercelayer.io/oauth/authorize?client_id={{your_client_id}}&redirect_uri={{your_redirect_uri}}&scope=market:id:xYZkjABcde&response_type=code&state=1a2b3c
  1. 一旦你授权了Webapp,你就会被重新定向到回调 URL:

    Callback URL with Authorization Code

    使用此代码获取访问令牌 :

import { authenticate } from "@commercelayer/js-auth"

const auth = await authenticate("authorization_code", {
  clientId: "<your_client_id>",
  clientSecret: "<your_client_secret>",
  callbackUrl: "<https://yourdomain.com/callback>",
  code: "<your_auth_code>"
})

console.log("My access token: ", auth.accessToken)
console.log("Expiration date: ", auth.expires)

规定适用

提供应用程序使用 客户证书 获取访问符的赠款类型.

步骤

  1. 访问您的个人 供给 在商务层仪表板上应用,并注意您提供的 API 证书(客户身份、客户秘密)

  2. 使用此代码获取访问令牌 :

import { authenticate } from "@commercelayer/js-auth"

const auth = await authenticate("client_credentials", {
  clientId: "<your_client_id>",
  clientSecret: "<your_client_secret>"
})

console.log("My access token: ", auth.accessToken)
console.log("Expiration date: ", auth.expires)

客户证书流程

对于高级使用时需要直接控制符管理的情况,可以绕过内置缓存辅助器(makeSalesChannel 财务报告和审定财务报表 makeIntegration并使用 authenticate 直接方法.

[尖叫声] 请注意,在这种情况下,你将负责 执行你自己的活塞 和刷新逻辑.

销售频道应用程序使用 客户证书 获得“客人”访问符的赠款类型.

import { authenticate } from "@commercelayer/js-auth"

const auth = await authenticate("client_credentials", {
  clientId: "<your_client_id>",
  scope: "market:code:europe"
})

console.log("My access token: ", auth.accessToken)
console.log("Expiration date: ", auth.expires)

集成应用程序使用 客户证书 获取访问符的赠款类型.

import { authenticate } from "@commercelayer/js-auth"

const auth = await authenticate("client_credentials", {
  clientId: "<your_client_id>",
  clientSecret: "<your_client_secret>",
})

console.log("My access token: ", auth.accessToken)
console.log("Expiration date: ", auth.expires)

公用事业

撤销一个符号

任何先前产生的访问令牌(包括新鲜令牌)都可以是 已撤销 在其自然到期日之前:

import { revoke } from "@commercelayer/js-auth"

await revoke({
  clientId: "<your_client_id>",
  clientSecret: "<your_client_secret>",
  token: "<a_generated_access_token>"
})

解码访问符

我们提供一种帮助方法 解码一个访问符。 返回已全部输入 .

[大 您不应将此用于不可信信件, 因为此帮助方法不会验证签名是否有效 。 如果你需要的话 验证访问符 在解码前可以使用 jwtVerify 换句话说.

import { authenticate, jwtDecode, jwtIsSalesChannel } from "@commercelayer/js-auth"

const auth = await authenticate("client_credentials", {
  clientId: "<your_client_id>",
  scope: "market:code:europe"
})

const decodedJWT = jwtDecode(auth.accessToken)

if (jwtIsSalesChannel(decodedJWT.payload)) {
  console.log("organization slug is", decodedJWT.payload.organization.slug)
}

正在验证访问符

我们提供一种帮助方法来验证一个访问符.

它验证了JWT的完整性和真实性. 它通过对照用于创建的公用钥匙验证签名,来检查该令牌是否有效.

这对确保信使没有被篡改和出自"商业地层"很有用.

返回已全部输入 :

import { authenticate, jwtVerify, jwtIsSalesChannel } from "@commercelayer/js-auth"

const auth = await authenticate("client_credentials", {
  clientId: "<your_client_id>",
  scope: "market:code:europe"
})

const decodedJWT = await jwtVerify(auth.accessToken, {
  ignoreExpiration: true
})

if (jwtIsSalesChannel(decodedJWT.payload)) {
  console.log("organization slug is", decodedJWT.payload.organization.slug)
}

获取核心 API 基准终点

传导 核心 API 基准终点 提供了有效的访问符.

import { getCoreApiBaseEndpoint } from "@commercelayer/js-auth"

getCoreApiBaseEndpoint("<a_valid_access_token>") //= "https://yourdomain.commercelayer.io"

该方法需要一个有效的访问符,并带有 organization 在有效载荷。 当组织没有设置时(例如,提供信使),它会发出一个 InvalidTokenError 除外.

获取提供 API 基端点

它还原 提供 API 基准终点 提供了有效的访问符.

import { getProvisioningApiBaseEndpoint } from "@commercelayer/js-auth"

getProvisioningApiBaseEndpoint("<a_valid_access_token>") //= "https://provisioning.commercelayer.io"

该方法需要有效的访问令牌(该令牌可与提供API一起使用). 当符号无效时(例如核心活字符号),它会扔出一个 InvalidTokenError 除外.


贡献者指南

  1. 叉头 此寄存器 (学习如何做到这一点) 这里) (中文(简体) ).

  2. 像这样砍掉叉子仓库:

git clone https://github.com/<your username>/commercelayer-js-auth.git && cd commercelayer-js-auth
  1. 更改并创建拉动请求( R)学着怎么做) (中文(简体) ).

  2. 有人会照顾你的拉力请求 并提供一些反馈.

需要帮忙吗?

许可证

此寄存器在 麻省理工学院 执照.

版本与发布记录

@commercelayer/js-auth 共发布 71 个版本,首次发布于 2019/11/29;过去 12 个月发布了 11 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
8.1.0latest2026/11/028 天前
8.0.22026/10/1328 天前
8.0.12026/08/212 个月前
8.0.02026/07/153 个月前
7.4.22026/05/205 个月前
7.4.12026/04/156 个月前

其他发布通道:next → 6.0.0-beta.2。

关于 @commercelayer/js-auth 的常见问题

@commercelayer/js-auth 是什么?

一个JavaScript库,旨在与商务地层API互动时简化认证.

如何安装 @commercelayer/js-auth?

在项目目录运行 npm install @commercelayer/js-auth,或使用 pnpm add / yarn add / bun add。

@commercelayer/js-auth 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@commercelayer/js-auth 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@commercelayer/js-auth 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@commercelayer/js-auth 可以商用吗?

@commercelayer/js-auth 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@commercelayer/js-auth 的下载量有多少?

根据 npm 官方下载统计,@commercelayer/js-auth 在 2026/10/11 – 2026/11/09 这 30 天内被下载 31,045 次,日均约 1,035 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@commercelayer/js-auth 还在维护吗?

最新版本 8.1.0 发布于 2026/11/02(8 天前);至今共发布 71 个版本,其中过去 12 个月发布了 11 个;首次发布于 2019/11/29。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。