@nihplod/sso-verify 1.0.0 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,18 +1,20 @@
1
1
  # @nihplod/sso-verify
2
2
 
3
- NIHPLOD 一网通 SSO Token 验证工具包 — 供子项目在后端验证主站签发的 Access Token。
3
+ NIHPLOD SSO token verification toolkit — for sub-projects to validate access tokens issued by the main site backend.
4
4
 
5
- ## 安装
5
+ ## Install
6
6
 
7
7
  ```bash
8
8
  npm install @nihplod/sso-verify
9
9
  ```
10
10
 
11
- ## 使用方式
11
+ ## Usage
12
12
 
13
- ### 方式一:Introspection 验证(推荐)
13
+ ### Method 1: Introspection (Recommended)
14
14
 
15
- 适用于所有子项目,无需接触签名密钥。
15
+ Suitable for all sub-projects; no signing keys required.
16
+
17
+ #### Confidential Client (server-side or BFF)
16
18
 
17
19
  ```typescript
18
20
  import { createTokenVerifier } from "@nihplod/sso-verify";
@@ -27,13 +29,30 @@ const verifier = createTokenVerifier({
27
29
 
28
30
  const payload = await verifier.verify(token);
29
31
  if (payload) {
30
- console.log(payload.sub); // 用户 ID
32
+ console.log(payload.sub); // User ID
31
33
  }
32
34
  ```
33
35
 
34
- ### 方式二:本地 JWT 验证(仅内部 Confidential Client)
36
+ #### Public Client (SPA / mobile / desktop)
37
+
38
+ Public Clients have no `client_secret`. The introspection endpoint still accepts verification with `client_id` only.
39
+
40
+ ```typescript
41
+ import { createTokenVerifier } from "@nihplod/sso-verify";
42
+
43
+ const verifier = createTokenVerifier({
44
+ introspectionEndpoint: "https://nihplod.cn/api/oauth/introspect",
45
+ clientId: "your-public-client-id",
46
+ audience: "your-public-client-id",
47
+ issuer: "https://nihplod.cn",
48
+ });
49
+
50
+ const payload = await verifier.verify(token);
51
+ ```
52
+
53
+ ### Method 2: Local JWT Verification (Internal Confidential Clients Only)
35
54
 
36
- 仅当子项目与主站共享 `JWT_ACCESS_SECRET` 时使用。
55
+ Only use this when the sub-project shares `JWT_ACCESS_SECRET` with the main site.
37
56
 
38
57
  ```typescript
39
58
  import { createTokenVerifier } from "@nihplod/sso-verify";
@@ -47,7 +66,7 @@ const verifier = createTokenVerifier({
47
66
  const payload = await verifier.verify(token);
48
67
  ```
49
68
 
50
- ## Express / Connect 中间件
69
+ ## Express / Connect Middleware
51
70
 
52
71
  ```typescript
53
72
  import { ssoMiddleware } from "@nihplod/sso-verify";
@@ -63,10 +82,10 @@ app.use(
63
82
  );
64
83
  ```
65
84
 
66
- 验证成功后,`req.user` 会挂载 token payload。
85
+ After successful verification, the token payload is attached to `req.user`.
67
86
 
68
- ## 注意事项
87
+ ## Notes
69
88
 
70
- - 当前主站默认使用 HS256 对称签名。对于外部子项目,推荐优先使用 **Introspection 模式** 验证 access_token。
71
- - 若你的子项目是内部服务且已与主站共享 RS256 公钥,可配置 `accessTokenPublicKey` 或 `jwksUri` 做本地 JWT 验证。
72
- - **不要将 `JWT_ACCESS_SECRET`(HS256 对称密钥)分发给外部子项目。**
89
+ - The main site currently uses HS256 symmetric signing by default. For external sub-projects, we recommend verifying access tokens via **Introspection**.
90
+ - If your sub-project is an internal service and already shares the RS256 public key with the main site, you can configure `accessTokenPublicKey` or `jwksUri` for local JWT verification.
91
+ - **Never distribute `JWT_ACCESS_SECRET` (the HS256 symmetric key) to external sub-projects.**
package/dist/index.js CHANGED
@@ -80,7 +80,7 @@ function createTokenVerifier(options) {
80
80
  return _rs256PublicKey;
81
81
  }
82
82
  async function introspect(token) {
83
- if (!introspectionEndpoint || !clientId || !clientSecret) {
83
+ if (!introspectionEndpoint || !clientId) {
84
84
  return null;
85
85
  }
86
86
  const cached = introspectCache.get(token);
@@ -88,14 +88,14 @@ function createTokenVerifier(options) {
88
88
  return { active: cached.active, ...cached.payload || {} };
89
89
  }
90
90
  try {
91
+ const params = new URLSearchParams({ token, client_id: clientId });
92
+ if (clientSecret) {
93
+ params.set("client_secret", clientSecret);
94
+ }
91
95
  const response = await fetch(introspectionEndpoint, {
92
96
  method: "POST",
93
97
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
94
- body: new URLSearchParams({
95
- token,
96
- client_id: clientId,
97
- client_secret: clientSecret
98
- })
98
+ body: params
99
99
  });
100
100
  if (!response.ok) return null;
101
101
  const data = await response.json();
package/dist/index.mjs CHANGED
@@ -54,7 +54,7 @@ function createTokenVerifier(options) {
54
54
  return _rs256PublicKey;
55
55
  }
56
56
  async function introspect(token) {
57
- if (!introspectionEndpoint || !clientId || !clientSecret) {
57
+ if (!introspectionEndpoint || !clientId) {
58
58
  return null;
59
59
  }
60
60
  const cached = introspectCache.get(token);
@@ -62,14 +62,14 @@ function createTokenVerifier(options) {
62
62
  return { active: cached.active, ...cached.payload || {} };
63
63
  }
64
64
  try {
65
+ const params = new URLSearchParams({ token, client_id: clientId });
66
+ if (clientSecret) {
67
+ params.set("client_secret", clientSecret);
68
+ }
65
69
  const response = await fetch(introspectionEndpoint, {
66
70
  method: "POST",
67
71
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
68
- body: new URLSearchParams({
69
- token,
70
- client_id: clientId,
71
- client_secret: clientSecret
72
- })
72
+ body: params
73
73
  });
74
74
  if (!response.ok) return null;
75
75
  const data = await response.json();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nihplod/sso-verify",
3
- "version": "1.0.0",
3
+ "version": "1.0.3",
4
4
  "description": "NIHPLOD 一网通 SSO Token 验证工具包 — 供子项目在后端验证主站签发的 Access Token",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",