商业层
轻量级 JavaScript 库,旨在简化 认证 当与商业层 API 交互时。 它提供了一种坚固的箱外缓存系统,支持可配置的持续存储、复合存储策略和专用的客户令牌管理.
它在任何地方都有作用——在你的浏览器,服务器上,或者在边缘.
什么是商业层?
商业层 是一个多市场商业API和订单管理系统,它允许您在任何网站,移动应用程序,聊天机,可穿戴,语音,或IoT设备中加入全局购物能力,轻松地. 用你已经掌握和热爱的最好的工具来整理你的堆叠. 通过一个快速的 企业级的 安全的API.
目录
开始
要开始商业层 JS Auth 你需要安装它 并添加到您的项目中.
安装
商业层 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或服务器上的内映映射),则一个客户代币将送达 每个 来客.
在服务器上安全存储客户代币有两种方式:
-
使用每个访客
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, }, ) -
使用自定义密钥共享存储 . 如果您宁愿在共享服务器侧存储器中缓存客户签名( 例如 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呼叫,而不需要其直接互动. 流动包括两个步骤:
-
开具附有客户索赔的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" } } } } }) -
将此断言交换为访问符
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 应用程序
仅供浏览器应用程序使用
网络应用程序使用 授权代码 授权类型以交换访问符的授权代码.
步骤
在此情况下,首先需要获得授权代码,然后用访问符交换:
-
创建商务层上的网络应用程序,并注意API证书(客户ID,客户端秘密,召回 URL,基端点,以及您想要设置范围的市场ID)
-
使用此 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
-
一旦你授权了Webapp,你就会被重新定向到回调 URL:
使用此代码获取访问令牌 :
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)
规定适用
提供应用程序使用 客户证书 获取访问符的赠款类型.
步骤
-
访问您的个人 供给 在商务层仪表板上应用,并注意您提供的 API 证书(客户身份、客户秘密)
-
使用此代码获取访问令牌 :
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 除外.
贡献者指南
git clone https://github.com/<your username>/commercelayer-js-auth.git && cd commercelayer-js-auth
-
更改并创建拉动请求( R)学着怎么做) (中文(简体) ).
-
有人会照顾你的拉力请求 并提供一些反馈.
需要帮忙吗?
- 联合 商业层的迪斯科德社区。 。 。 .
- 让我们继续 布鲁斯基, (中文(简体) ), 页:1,或 链接。 。 。 .
- 有虫子吗? 创建一个 问题 。在此仓库上.
许可证
此寄存器在 麻省理工学院 执照.