@nihplod/sso-verify 1.0.2 → 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
@@ -14,6 +14,8 @@ npm install @nihplod/sso-verify
14
14
 
15
15
  Suitable for all sub-projects; no signing keys required.
16
16
 
17
+ #### Confidential Client (server-side or BFF)
18
+
17
19
  ```typescript
18
20
  import { createTokenVerifier } from "@nihplod/sso-verify";
19
21
 
@@ -31,6 +33,23 @@ if (payload) {
31
33
  }
32
34
  ```
33
35
 
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
+
34
53
  ### Method 2: Local JWT Verification (Internal Confidential Clients Only)
35
54
 
36
55
  Only use this when the sub-project shares `JWT_ACCESS_SECRET` with the main site.
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.2",
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",