lgsso-sdk 1.0.94 → 1.0.96
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 +206 -63
- package/package.json +1 -1
- package/src/sso.js +23 -5
package/README.md
CHANGED
|
@@ -1,163 +1,306 @@
|
|
|
1
1
|
# lg-ssosdk
|
|
2
2
|
|
|
3
|
-
LG-SSO SDK
|
|
3
|
+
LG-SSO SDK 是一个无框架依赖的单点登录(SSO)JavaScript 库,提供 token 管理、登录状态维护、注销、跨应用跳转等功能,可帮助 Web 应用快速集成 SSO 认证机制。
|
|
4
4
|
|
|
5
5
|
## 安装
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
\# 使用 npm 安装
|
|
11
|
+
|
|
7
12
|
npm install lg-ssosdk
|
|
8
13
|
|
|
9
|
-
|
|
14
|
+
\# 使用 yarn 安装
|
|
15
|
+
|
|
10
16
|
yarn add lg-ssosdk
|
|
17
|
+
```
|
|
18
|
+
|
|
11
19
|
## 引入方式
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
```
|
|
12
24
|
// 引入默认实例
|
|
25
|
+
|
|
13
26
|
import lgsso from 'lg-ssosdk';
|
|
14
27
|
|
|
15
28
|
// 或创建自定义实例
|
|
29
|
+
|
|
16
30
|
import { createSSO } from 'lg-ssosdk';
|
|
31
|
+
|
|
17
32
|
const customSSO = createSSO();
|
|
33
|
+
```
|
|
34
|
+
|
|
18
35
|
## 初始化配置
|
|
19
36
|
|
|
20
|
-
使用SDK
|
|
37
|
+
使用 SDK 前必须先调用 `init` 方法进行初始化配置:
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
```
|
|
21
42
|
lgsso.init({
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
43
|
+
|
|
44
|
+
accessCodeKey: 'accessCode', // accessCode 在 URL 中的参数名
|
|
45
|
+
|
|
46
|
+
tokenKey: 'scm\_token', // token 在存储中的键名
|
|
47
|
+
|
|
48
|
+
timeout: 5000, // 请求超时时间(毫秒)
|
|
49
|
+
|
|
25
50
|
headers: {}, // 自定义请求头
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
51
|
+
|
|
52
|
+
tokenApi: '/api/token', // 通过 accessCode 获取 token 的 API 地址(必填)
|
|
53
|
+
|
|
54
|
+
refreshCodeApi: '/api/refresh', // 刷新 accessCode 的 API 地址
|
|
55
|
+
|
|
56
|
+
logoutApi: '/api/logout', // 注销 API 地址
|
|
57
|
+
|
|
58
|
+
logOutUrl: '/login', // 登录页面 URL
|
|
59
|
+
|
|
60
|
+
storage: localStorage, // 存储方式(localStorage/sessionStorage)
|
|
61
|
+
|
|
31
62
|
})
|
|
63
|
+
|
|
32
64
|
.then(result => {
|
|
65
|
+
|
|
33
66
|
console.log('初始化结果:', result);
|
|
67
|
+
|
|
34
68
|
});
|
|
69
|
+
```
|
|
70
|
+
|
|
35
71
|
### 配置参数说明
|
|
36
72
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
|
40
|
-
|
|
|
41
|
-
|
|
|
42
|
-
|
|
|
43
|
-
|
|
|
44
|
-
|
|
|
45
|
-
|
|
|
46
|
-
|
|
|
47
|
-
|
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
| 参数名 | 类型 | 默认值 | 说明 |
|
|
76
|
+
| -------------- | ------ | ------------ | ----------------------------------- |
|
|
77
|
+
| accessCodeKey | String | 'accessCode' | accessCode 在 URL 中的参数名 |
|
|
78
|
+
| tokenKey | String | 'scm\_token' | token 在 storage 中的存储键名 |
|
|
79
|
+
| timeout | Number | 5000 | 请求超时时间(ms) |
|
|
80
|
+
| headers | Object | {} | 自定义请求头 |
|
|
81
|
+
| tokenApi | String | '' | 通过 accessCode 获取 token 的 API 地址(必填) |
|
|
82
|
+
| refreshCodeApi | String | '' | 刷新 accessCode 的 API 地址 |
|
|
83
|
+
| logoutApi | String | '' | 注销 API 地址 |
|
|
84
|
+
| logOutUrl | String | '' | 登录页面 URL |
|
|
85
|
+
| storage | Object | localStorage | 存储方式,需实现 setItem 和 getItem 方法 |
|
|
48
86
|
|
|
49
87
|
## 核心方法
|
|
50
88
|
|
|
51
89
|
### init(options)
|
|
52
90
|
|
|
53
|
-
初始化SDK,合并配置并验证有效性。如果URL中存在accessCode,会自动获取token;如果没有token,会跳转到登录页。
|
|
91
|
+
初始化 SDK,合并配置并验证有效性。如果 URL 中存在 accessCode,会自动获取 token;如果没有 token,会跳转到登录页。
|
|
54
92
|
|
|
55
93
|
**参数**:
|
|
56
|
-
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
* `options`:配置选项,详见初始化配置部分
|
|
57
98
|
|
|
58
99
|
**返回**:`Promise<Object>` - 初始化结果
|
|
59
100
|
|
|
60
101
|
### getToken()
|
|
61
102
|
|
|
62
|
-
获取存储的token值。
|
|
103
|
+
获取存储的 token 值。
|
|
63
104
|
|
|
64
|
-
**返回**:`String|null` - token值或null
|
|
105
|
+
**返回**:`String|null` - token 值或 null
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
```
|
|
65
110
|
const token = lgsso.getToken();
|
|
111
|
+
|
|
66
112
|
console.log('当前token:', token);
|
|
113
|
+
```
|
|
114
|
+
|
|
67
115
|
### removeToken()
|
|
68
116
|
|
|
69
|
-
删除存储的token。
|
|
117
|
+
删除存储的 token。
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
```
|
|
70
122
|
lgsso.removeToken();
|
|
123
|
+
```
|
|
124
|
+
|
|
71
125
|
### logout()
|
|
72
126
|
|
|
73
|
-
退出登录,调用logoutApi并清除token,然后跳转到登录页。
|
|
127
|
+
退出登录,调用 logoutApi 并清除 token,然后跳转到登录页。
|
|
74
128
|
|
|
75
129
|
**返回**:`Promise<Object>` - 退出结果
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
```
|
|
76
134
|
lgsso.logout()
|
|
135
|
+
|
|
77
136
|
.then(result => {
|
|
137
|
+
|
|
78
138
|
console.log('退出结果:', result);
|
|
139
|
+
|
|
79
140
|
});
|
|
80
|
-
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### toUrl(redirectUrl, target)
|
|
81
144
|
|
|
82
|
-
使用当前token换取新的accessCode,并跳转到指定URL(自动在URL后添加accessCode参数)。
|
|
145
|
+
使用当前 token 换取新的 accessCode,并跳转到指定 URL(自动在 URL 后添加 accessCode 参数)。
|
|
83
146
|
|
|
84
147
|
**参数**:
|
|
85
|
-
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
* `redirectUrl`:目标跳转地址
|
|
152
|
+
|
|
153
|
+
* `target`:跳转方式,支持 `'_self'`(当前页面,默认)和 `'_blank'`(新页面)
|
|
86
154
|
|
|
87
155
|
**返回**:`Promise<Object>` - 操作结果
|
|
88
|
-
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
// 在当前页面打开(默认)
|
|
161
|
+
|
|
162
|
+
lgsso.toUrl('https://example.com/target', '\_self')
|
|
163
|
+
|
|
89
164
|
.then(result => {
|
|
165
|
+
|
|
90
166
|
console.log('跳转准备结果:', result);
|
|
167
|
+
|
|
91
168
|
});
|
|
169
|
+
|
|
170
|
+
// 在新页面打开
|
|
171
|
+
|
|
172
|
+
lgsso.toUrl('https://example.com/target', '\_blank');
|
|
173
|
+
```
|
|
174
|
+
|
|
92
175
|
### getAccessCode()
|
|
93
176
|
|
|
94
|
-
使用当前token换取新的accessCode。
|
|
177
|
+
使用当前 token 换取新的 accessCode。
|
|
178
|
+
|
|
179
|
+
**返回**:`Promise<Object>` - 包含 accessCode 的结果(在 data 字段中)
|
|
95
180
|
|
|
96
|
-
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
```
|
|
97
184
|
lgsso.getAccessCode()
|
|
185
|
+
|
|
98
186
|
.then(result => {
|
|
187
|
+
|
|
99
188
|
if (result.code === 0) {
|
|
189
|
+
|
|
100
190
|
console.log('新的accessCode:', result.data);
|
|
191
|
+
|
|
101
192
|
}
|
|
102
|
-
});
|
|
103
|
-
### getConfig()
|
|
104
193
|
|
|
105
|
-
|
|
194
|
+
});
|
|
195
|
+
```
|
|
106
196
|
|
|
107
|
-
**返回**:`Object|null` - 当前配置
|
|
108
|
-
const config = lgsso.getConfig();
|
|
109
|
-
console.log('当前配置:', config);
|
|
110
197
|
## 错误码说明
|
|
111
198
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
|
115
|
-
|
|
|
116
|
-
| -
|
|
117
|
-
| -
|
|
118
|
-
| -
|
|
119
|
-
| -
|
|
120
|
-
| -
|
|
121
|
-
| -
|
|
122
|
-
| -
|
|
123
|
-
| -
|
|
124
|
-
| -
|
|
125
|
-
| -
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
| 错误码 | 说明 |
|
|
202
|
+
| ---- | ------------------------------------- |
|
|
203
|
+
| -100 | 初始化相关错误(如缺少配置、配置无效等) |
|
|
204
|
+
| -101 | 未初始化(需先调用 init 方法) |
|
|
205
|
+
| -102 | 未配置 logoutApi |
|
|
206
|
+
| -103 | 退出登录失败 |
|
|
207
|
+
| -104 | 跳转地址为空 |
|
|
208
|
+
| -105 | 未配置 refreshCodeApi |
|
|
209
|
+
| -106 | 未找到有效 token |
|
|
210
|
+
| -107 | 跳转失败 |
|
|
211
|
+
| -108 | target 参数无效(必须是 '\_self' 或 '\_blank') |
|
|
212
|
+
| -200 | 非浏览器环境使用 request 方法 |
|
|
213
|
+
| -201 | 响应数据不是有效的 JSON 格式 |
|
|
214
|
+
| -202 | 请求超时 |
|
|
215
|
+
| -203 | 网络请求失败 |
|
|
126
216
|
|
|
127
217
|
## 使用示例
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
```
|
|
128
222
|
// 初始化SDK
|
|
223
|
+
|
|
129
224
|
lgsso.init({
|
|
225
|
+
|
|
130
226
|
tokenApi: '/api/getToken',
|
|
227
|
+
|
|
131
228
|
refreshCodeApi: '/api/refreshCode',
|
|
229
|
+
|
|
132
230
|
logoutApi: '/api/logout',
|
|
231
|
+
|
|
133
232
|
logOutUrl: '/login'
|
|
233
|
+
|
|
134
234
|
})
|
|
235
|
+
|
|
135
236
|
.then(initResult => {
|
|
237
|
+
|
|
136
238
|
console.log('初始化结果:', initResult);
|
|
239
|
+
|
|
137
240
|
|
|
241
|
+
|
|
138
242
|
// 获取token
|
|
243
|
+
|
|
139
244
|
const token = lgsso.getToken();
|
|
245
|
+
|
|
140
246
|
console.log('当前token:', token);
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
// 跳转到其他应用(当前页面)
|
|
251
|
+
|
|
252
|
+
document.getElementById('gotoCurrent').addEventListener('click', () => {
|
|
253
|
+
|
|
254
|
+
lgsso.toUrl('https://other-app.example.com', '\_self')
|
|
255
|
+
|
|
256
|
+
.catch(err => console.error('跳转失败:', err));
|
|
257
|
+
|
|
258
|
+
});
|
|
259
|
+
|
|
141
260
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
261
|
+
|
|
262
|
+
// 跳转到其他应用(新页面)
|
|
263
|
+
|
|
264
|
+
document.getElementById('gotoNew').addEventListener('click', () => {
|
|
265
|
+
|
|
266
|
+
lgsso.toUrl('https://other-app.example.com', '\_blank')
|
|
267
|
+
|
|
145
268
|
.catch(err => console.error('跳转失败:', err));
|
|
269
|
+
|
|
146
270
|
});
|
|
271
|
+
|
|
147
272
|
|
|
273
|
+
|
|
148
274
|
// 退出登录
|
|
275
|
+
|
|
149
276
|
document.getElementById('logoutBtn').addEventListener('click', () => {
|
|
277
|
+
|
|
150
278
|
lgsso.logout()
|
|
279
|
+
|
|
151
280
|
.catch(err => console.error('退出失败:', err));
|
|
281
|
+
|
|
152
282
|
});
|
|
283
|
+
|
|
153
284
|
})
|
|
285
|
+
|
|
154
286
|
.catch(err => {
|
|
287
|
+
|
|
155
288
|
console.error('初始化失败:', err);
|
|
289
|
+
|
|
156
290
|
});
|
|
291
|
+
```
|
|
292
|
+
|
|
157
293
|
## 注意事项
|
|
158
294
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
1. 必须先调用 `init` 方法初始化后才能使用其他方法
|
|
298
|
+
|
|
299
|
+
2. `tokenApi` 是必填配置项,用于通过 accessCode 获取 token
|
|
300
|
+
|
|
301
|
+
3. 在非浏览器环境下使用时,部分依赖浏览器 API 的功能将不可用
|
|
302
|
+
|
|
303
|
+
4. 建议在应用入口处进行初始化,确保整个应用生命周期中都能使用 SSO 功能
|
|
304
|
+
|
|
305
|
+
5. 使用 `toUrl` 方法时,`target` 参数仅支持 `'_self'` 和 `'_blank'` 两个值,默认使用 `'_self'`
|
|
306
|
+
|
package/package.json
CHANGED
package/src/sso.js
CHANGED
|
@@ -150,9 +150,10 @@ export function createSSO() {
|
|
|
150
150
|
/**
|
|
151
151
|
* 用token换取新accessCode并跳转到指定URL
|
|
152
152
|
* @param {string} redirectUrl - 目标跳转地址
|
|
153
|
+
* @param {string} target - 当前页面:_self、新页面打开:_blank,默认当前页_self
|
|
153
154
|
* @returns {Promise<Object>} 接口返回结果
|
|
154
155
|
*/
|
|
155
|
-
async toUrl(redirectUrl) {
|
|
156
|
+
async toUrl(redirectUrl, target = '_self') { // 新增target参数,默认当前页面
|
|
156
157
|
if (!config) {
|
|
157
158
|
return { code: -101, msg: '请先调用init方法初始化', success: false };
|
|
158
159
|
}
|
|
@@ -161,6 +162,11 @@ export function createSSO() {
|
|
|
161
162
|
return { code: -104, msg: '请提供跳转地址', success: false };
|
|
162
163
|
}
|
|
163
164
|
|
|
165
|
+
// 验证target参数有效性
|
|
166
|
+
if (!['_self', '_blank'].includes(target)) {
|
|
167
|
+
return { code: -108, msg: 'target参数必须是"_self"或"_blank"', success: false };
|
|
168
|
+
}
|
|
169
|
+
|
|
164
170
|
if (!config.refreshCodeApi) {
|
|
165
171
|
return { code: -105, msg: '未配置refreshCodeApi', success: false };
|
|
166
172
|
}
|
|
@@ -168,8 +174,14 @@ export function createSSO() {
|
|
|
168
174
|
const token = this.getToken();
|
|
169
175
|
if (!token) {
|
|
170
176
|
if (isBrowser() && config.logOutUrl) {
|
|
171
|
-
|
|
172
|
-
|
|
177
|
+
const loginUrl = `${config.logOutUrl}?redirect_uri=${encodeURIComponent(redirectUrl)}`;
|
|
178
|
+
|
|
179
|
+
// 根据target决定打开方式
|
|
180
|
+
if (target === '_blank') {
|
|
181
|
+
window.open(loginUrl, '_blank');
|
|
182
|
+
} else {
|
|
183
|
+
window.location.href = loginUrl;
|
|
184
|
+
}
|
|
173
185
|
}
|
|
174
186
|
return { code: -106, msg: '未找到有效token', success: false };
|
|
175
187
|
}
|
|
@@ -187,7 +199,14 @@ export function createSSO() {
|
|
|
187
199
|
if (result.code === 0 && result.data && isBrowser()) {
|
|
188
200
|
const url = new URL(redirectUrl);
|
|
189
201
|
url.searchParams.set(config.accessCodeKey, result.data);
|
|
190
|
-
|
|
202
|
+
const targetUrl = url.toString();
|
|
203
|
+
|
|
204
|
+
// 根据target参数决定跳转方式
|
|
205
|
+
if (target === '_blank') {
|
|
206
|
+
window.open(targetUrl, '_blank');
|
|
207
|
+
} else {
|
|
208
|
+
window.location.href = targetUrl;
|
|
209
|
+
}
|
|
191
210
|
}
|
|
192
211
|
|
|
193
212
|
return result;
|
|
@@ -195,7 +214,6 @@ export function createSSO() {
|
|
|
195
214
|
return { code: -107, msg: `跳转失败: ${error.message}`, success: false };
|
|
196
215
|
}
|
|
197
216
|
},
|
|
198
|
-
|
|
199
217
|
/**
|
|
200
218
|
* 获取accessCode(通过token换取)
|
|
201
219
|
* @returns {Promise<Object>} 接口返回结果(data为accessCode)
|