@ descope/web-js- sdk (英语)
扫描器 JavaScript 网络 SDK
使用量
安装软件包
npm install @descope/web-js-sdk
用这个
import descopeSdk from '@descope/web-js-sdk';
const myProjectId = 'xxx';
const sdk = descopeSdk({
/* Descope Project ID (Required) */
projectId: myProjectId,
/* Persist tokens that returned after successful authentication (e.g. sdk.otp.verify.email(...),
sdk.refresh(...), flow.next(...), etc.) in browser storage. In addition, this will
make `sdk.getSessionToken()` available, see usage bellow bellow */
persistTokens: true,
/* Pass `sessionTokenViaCookie: true` to store the session token in a cookie when using `persistTokens`. By default, the sdk will set the session token in the browser storage.
You can also pass an object to customize cookie options, e.g. `sessionTokenViaCookie: { sameSite: 'Lax', secure: false, cookieName: 'MY_COOKIE' }`.
- `sameSite` (default: `Strict`) – Controls the SameSite attribute of the session cookie.
- `secure` (default: `true`) – If true, sets the cookie as Secure (sent only over HTTPS).
- `cookieName` (default: `DS`) – The name of the session token cookie. Useful for avoiding conflicts when running multiple Descope projects on the same domain.
- `domain` (default: auto-detected) – The domain for the session token cookie. If not specified, uses the domain from Descope project settings or current domain.
Notes:
- This option is relevant only when `persistTokens` is true.
- The session token cookie is set as a [`Secure`](https://datatracker.ietf.org/doc/html/rfc6265#section-5.2.5) cookie. It will be sent only over HTTPS connections.
In addition, some browsers (e.g. Safari) may not store `Secure` cookie if the hosted page is running on an HTTP protocol.
- The session token cookie is set to [`SameSite=Strict; Secure;`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie) by default.
If you need to customize this, you can set `sessionTokenViaCookie: {sameSite: 'Lax', secure: false, cookieName: 'MY_COOKIE'}` (if you pass only `sameSite`, `secure` will be set to `true` by default, and `cookieName` will default to `DS`).
- If the cookie domain set on Descope configuration doesn't match, or is not a parent domain of the current domain, The cookie will be stored on the current domain that runs the code. Examples:
- Project cookie domain is acme.com, current domain is app.acme.com - the domain will be set to app.acme.com
- Project cookie domain is acme.com, current domain is my-app.com - the domain will be set to my-app.com
*/
*/
sessionTokenViaCookie: false,
/* Automatically schedule a call refresh session call after a successful authentication:
Note: due to browser limitation, the maximum interval for the refresh has an upper bound of 2^32 - 1 milliseconds (approximately 24.8 days).
*/
autoRefresh: true,
/* Disable storing the last authenticated user details on the browser storage (default is true).
Note: Disabling this flag may cause features related to the last-authenticated user to not function properly.
*/
storeLastAuthenticatedUser: false, // default is true
/* Do not clear the last authenticated user details from the browser storage after logout (default is false).
Note: This flag is relevant only when `storeLastAuthenticatedUser` is true.
*/
keepLastAuthenticatedUserAfterLogout: true, // default is false
/* When managing multiple Descope projects on the same domain, you can prevent refresh cookie conflicts by assigning a custom name to your refresh token cookie during the login process (for example, using Descope Flows). However, you must also configure the SDK to recognize this unique name by passing the `refreshCookieName` option.
*/
refreshCookieName: "cookie-1"
// Pass this function to the SDK if you want to seamlessly migrate session from an external authentication provider to Descope.
getExternalToken: async () => {
// Bring token from external provider (e.g. get access token from another auth provider)
return 'my-external-token';
},
});
sdk.onSessionTokenChange((newSession, oldSession) => {
// handle session token change...
// Note that if Descope project settings are configured to manage session token in cookies, the session token will not be available in the browser.
});
sdk.onIsAuthenticatedChange((isAuthenticated) => {
// handle authentication change...
});
sdk.onUserChange((newUser, oldUser) => {
// handle user change...
});
sdk.onClaimsChange((newClaims) => {
// handle Claims change...
});
/* For a case that the browser has a valid refresh token on storage/cookie,
the user should get a valid session token (e.i. user should be logged-in).
For that purpose, it is common to call the refresh function after sdk initialization.
Note: Refresh return a session token, so if the autoRefresh was provided, the sdk will
automatically continue to refresh the token */
sdk.refresh();
// Alternatively - use the sdk's available authentication methods to authenticate the user
const userIdentifier = 'identifier';
let res = await sdk.otp.signIn.email(userIdentifier);
if (!res.ok) {
throw Error('Failed to sign in');
}
// Get the one time code from email and verify it
const codeFromEmail = '1234';
res = await sdk.otp.verify.email(userIdentifier, codeFromEmail);
if (!res.ok) {
throw Error('Failed to sign in');
}
// Get session token
// Can be used to pass token to server on header
const sessionToken = sdk.getSessionToken();
使用 OIDC
Descope也支持OIDC登录. 要启用 OIDC 登录, 通过 oidcConfig sDK 初始化属性。 这个 oidcConfig 属性是布尔或配置对象。 如果你通过了 oidcConfig: true, SDK 将使用 Descope 的 OIDC 默认应用程序
// Initialize the SDK with OIDC
const sdk = descopeSdk({
projectId: 'xxx',
oidcConfig: true,
});
// Initialize the SDK with custom OIDC application
const sdk = descopeSdk({
projectId: 'xxx',
oidcConfig: {
applicationId: 'my-application-id', // optional, if not provided, the default OIDC application will be used
redirectUri: 'https://my-app.com/redirect', // optional, if not provided, the default redirect URI will be used
scope: 'openid profile email', // optional, if not provided, default is openid email offline_access roles descope.custom_claims
},
});
使用输入应用程序作为 OIDC 提供者
要使用入境应用程序作为OIDC的提供者,您必须同时提供 issuer 财务报告和审定财务报表 clientId 配置选项。 这个 issuer 是 OIDC 权威 URL,并且 clientId 是您入境应用程序的客户身份 .
说明: 当将一个入境应用程序配置为 OIDC 提供者时, 您必须直接从 Descope 控制台中的入境应用程序设置页面获取发行器 URL 。 发行者 URL 是您输入的应用程序配置所特有的, 无法手动构建 。 此外,您还需要从相同的入境应用程序设置中提供客户端ID.
// Initialize the SDK with inbound app OIDC configuration
const sdk = descopeSdk({
projectId: 'xxx',
oidcConfig: {
// Required: Get this from your inbound app settings page
issuer: 'https://api.descope.com/v1/apps/P1234567890',
// Required: Client ID from your inbound app settings
clientId: 'your-inbound-app-client-id',
// Optional: Custom redirect URI (defaults to current URL)
redirectUri: 'https://my-app.com/redirect',
// Optional: Custom scope (defaults to 'openid' when issuer is provided)
scope: 'openid profile email',
},
});
使用自定义时 issuer 默认范围为 'openid' 而不是整个Descope范围。 您可以通过提供自定义来覆盖此功能 scope 数值.
开始 OIDC 登录
登录 OIDC 是通过调用 loginWithRedirect 方法。 这种方法将把用户重定向到Descope OIDC登录页面. 在用户登录后,它们会被重新定向回应用程序来完成登录过程.
await sdk.oidc.loginWithRedirect({
// By default, the login will redirect the user to the current URL
// If you want to redirect the user to a different URL, you can specify it here
redirect_uri: window.location.origin,
});
完成 OIDC 登录
在用户被重定向回应用程序后,您需要调用 oidc 代码和状态查询参数 oidc.finishLogin 或者说 oidc.finishLoginIfNeed 完成登录过程的方法
使用 finishLoginIfNeed (建议):
// Call this method to finish the login process.
// This method will only finish the login process if the user was redirected back to the application after login.
await sdk.oidc.finishLoginIfNeed();
使用 finishLogin数字 :
// Call this method to finish the login process, which takes the code and state query parameters from the URL, and exchanges them for a session
// Note: Call this method only if the user was redirected back to the application after login, this is usually done according the the code/state query parameters
await sdk.oidc.finishLogin();
管理 OIDC 会话
SDK会自动为您管理 OIDC 会话, 根据 persistTokens 财务报告和审定财务报表 autoRefresh 选项。 SDK将在OIDC会话到期后自动刷新,并将会话令牌存储在浏览器存储或cookie中,按照 persistTokens 选项.
基于活动的会话刷新
何时 autoRefresh: { customActivityTracking: true }, SDK 跳过空闲用户的刷新呼叫. 这减少了不必要的API呼叫,并使得服务器上能够精确地进行会话无活性跟踪. 开发者负责呼叫 sdk.markUserActive() 以指示用户活动.
const sdk = descopeSdk({
projectId: 'xxx',
autoRefresh: { customActivityTracking: true },
});
// Call this whenever the user interacts with your app
document.addEventListener('click', () => sdk.markUserActive());
document.addEventListener('keydown', () => sdk.markUserActive());
行为:
- 当时间点燃时
markUserActive()自上次刷新后没有调用 : 跳过刷新, 标记为跳过 - 何时
markUserActive()在跳过刷新后调用: 触发立即刷新 - 当时间点燃时
markUserActive()被调用: 正常刷新 - 成功刷新后: 活动旗被重新设置( 下次刷新期开始为新)
sdk.markUserActive()总是可用的——它记录一个警告,当customActivityTracking未设置
当启用 Descope 的会话不活动特性时, 这样做是有用的, 确保刷新只针对真正活跃的用户 .
自定义存储
默认情况下, SDK 读写到 window.localStorage 用于需要超过单个页面载荷的状态(上一个认证的用户,没有被存储在饼干中时的指使等). 若为 localStorage 无法使用, 或者您想要用其它东西支持这些密钥 sessionStorage,一个内存商店,一个加密的包装机,一个跨框桥——通过一个 customStorage 对象为 SDK.
const inMemoryStorage = (() => {
const map = new Map();
return {
getItem: (key) => (map.has(key) ? map.get(key) : null),
setItem: (key, value) => {
map.set(key, value);
},
removeItem: (key) => {
map.delete(key);
},
};
})();
const sdk = descopeSdk({
projectId: 'xxx',
customStorage: inMemoryStorage,
});
对象必须执行 CustomStorage 接口 :
type CustomStorage = {
getItem: (key: string) => string | null;
setItem: (key: string, value: string) => void;
removeItem: (key: string) => void;
};
说明:
customStorage备份 SDK 代表您坚持的密钥( 键, 最后的认证用户 )。 确保您的执行绕行 这些密钥干净地 -getItem(key)返回上次传输到的字符串setItem(key, value)。如果您的存储键下降、 过滤器或命名空间, 使其无法在回程中幸存, 依赖于它们的特性可能会退化 .客户端会话更新优化的内部非PII标记(
DSLI编号 :DSLI_DISABLED)是例外:SDK总是让他们真实存在window.localStorage,独立于customStorage。这就是使优化行为正确的原因,即使你用其他键返回sessionStorage或入门行.
最后登录指标
SDK维持着一个 DSLI (目镜会话登录指标) window.localStorage - 总是,即使当一个 customStorage 提供了 —— 跟踪此浏览器是否先前有过活动认证的会话 。 在每一个成功的认证, DSLI 已写入。 在登录或无效会话响应时,它将被清除 .
何时 sdk.refresh() 在“ try-refresh”模式中(即在 SDK 初始化上,以恢复前一个会话), SDK 将全部跳过网络调用, 如果没有 DSLI 或最后一个用户的密钥( e)dls_last_user_login_id)在场。 这样可以消除多余的 /v1/auth/try-refresh 为从未登入的匿名访客往返.
说明: 如果你准备好了
storeLastAuthenticatedUser: false, (中文(简体) ),dls_last_user_login_id从来没有写。 在这种情况下,只有DSLI可用作指标。 现有经认证的用户在使用新的SDK版本认证后,将按预期触发刷新.
运行示例
举例来说:
- 安装依赖关系
pnpm i - 运行样本
pnpm run start
浏览器打开一个带有可用示例的目录树的标签. 点击欲望目录并遵循指令 .
注: 这个包是单列波的一部分. 所以,如果您在依赖关系上有所改变,您必须重新运行 npm run start (这是暂时的解决方案,直到我们改进过程以适应单重).