@pubinfo/module-auth 2.0.0-beta.14
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/dist/index.cjs +221 -0
- package/dist/index.d.cts +33 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +196 -0
- package/dist/interface-C_qnbvmk.d.cts +50 -0
- package/dist/interface-C_qnbvmk.d.ts +50 -0
- package/dist/providers/4A.cjs +43 -0
- package/dist/providers/4A.d.cts +9 -0
- package/dist/providers/4A.d.ts +9 -0
- package/dist/providers/4A.js +22 -0
- package/dist/providers/credentials.cjs +34 -0
- package/dist/providers/credentials.d.cts +12 -0
- package/dist/providers/credentials.d.ts +12 -0
- package/dist/providers/credentials.js +13 -0
- package/dist/providers/ding-zj.cjs +80 -0
- package/dist/providers/ding-zj.d.cts +17 -0
- package/dist/providers/ding-zj.d.ts +17 -0
- package/dist/providers/ding-zj.js +59 -0
- package/package.json +33 -0
- package/src/core.ts +114 -0
- package/src/index.ts +86 -0
- package/src/interface.ts +60 -0
- package/src/pages/auth.ts +42 -0
- package/src/providers/4A.ts +24 -0
- package/src/providers/credentials.ts +19 -0
- package/src/providers/ding-zj.ts +76 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/providers/credentials.ts
|
|
21
|
+
var credentials_exports = {};
|
|
22
|
+
__export(credentials_exports, {
|
|
23
|
+
default: () => Credentials
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(credentials_exports);
|
|
26
|
+
function Credentials(options) {
|
|
27
|
+
const { authorize } = options;
|
|
28
|
+
return {
|
|
29
|
+
id: "credentials",
|
|
30
|
+
name: "\u51ED\u8BC1\u767B\u5F55",
|
|
31
|
+
type: "custom",
|
|
32
|
+
authorization: authorize
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { F as Fn, c as ProviderConfig } from '../interface-C_qnbvmk.cjs';
|
|
2
|
+
import 'vue-router';
|
|
3
|
+
|
|
4
|
+
interface CredentialsConfig {
|
|
5
|
+
authorize: Fn<any>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* 凭证登录
|
|
9
|
+
*/
|
|
10
|
+
declare function Credentials(options: CredentialsConfig): ProviderConfig;
|
|
11
|
+
|
|
12
|
+
export { Credentials as default };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { F as Fn, c as ProviderConfig } from '../interface-C_qnbvmk.js';
|
|
2
|
+
import 'vue-router';
|
|
3
|
+
|
|
4
|
+
interface CredentialsConfig {
|
|
5
|
+
authorize: Fn<any>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* 凭证登录
|
|
9
|
+
*/
|
|
10
|
+
declare function Credentials(options: CredentialsConfig): ProviderConfig;
|
|
11
|
+
|
|
12
|
+
export { Credentials as default };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// src/providers/credentials.ts
|
|
2
|
+
function Credentials(options) {
|
|
3
|
+
const { authorize } = options;
|
|
4
|
+
return {
|
|
5
|
+
id: "credentials",
|
|
6
|
+
name: "\u51ED\u8BC1\u767B\u5F55",
|
|
7
|
+
type: "custom",
|
|
8
|
+
authorization: authorize
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
Credentials as default
|
|
13
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/providers/ding-zj.ts
|
|
21
|
+
var ding_zj_exports = {};
|
|
22
|
+
__export(ding_zj_exports, {
|
|
23
|
+
default: () => DingZJ
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(ding_zj_exports);
|
|
26
|
+
function DingZJ(options) {
|
|
27
|
+
const { clientId, redirectUri } = options;
|
|
28
|
+
const authorization = {
|
|
29
|
+
/** 跳转外部页面 */
|
|
30
|
+
redirect: {
|
|
31
|
+
url: "https://openplatform-pro.ding.zj.gov.cn/oauth2/auth.htm",
|
|
32
|
+
params: {
|
|
33
|
+
response_type: "code",
|
|
34
|
+
client_id: clientId,
|
|
35
|
+
redirect_uri: redirectUri,
|
|
36
|
+
scope: "get_user_info",
|
|
37
|
+
authType: "QRCODE"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
/** 内嵌二维码 */
|
|
41
|
+
embed: {
|
|
42
|
+
url: "https://login-pro.ding.zj.gov.cn/oauth2/auth.htm",
|
|
43
|
+
params: {
|
|
44
|
+
response_type: "code",
|
|
45
|
+
client_id: clientId,
|
|
46
|
+
redirect_uri: redirectUri,
|
|
47
|
+
scope: "get_user_info",
|
|
48
|
+
authType: "QRCODE",
|
|
49
|
+
embedMode: "true"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const initQRCode = (url, options2) => {
|
|
54
|
+
const target = document.getElementById(options2.id);
|
|
55
|
+
if (!target) {
|
|
56
|
+
throw new Error(`\u672A\u627E\u5230id\u4E3A${options2.id}\u7684DOM\u5143\u7D20`);
|
|
57
|
+
}
|
|
58
|
+
const iframe = document.createElement("iframe");
|
|
59
|
+
iframe.src = url;
|
|
60
|
+
iframe.width = "200";
|
|
61
|
+
iframe.height = "200";
|
|
62
|
+
document.appendChild(iframe);
|
|
63
|
+
window.addEventListener("message", (e) => {
|
|
64
|
+
if (options2.redirectUri) {
|
|
65
|
+
const url2 = new URL(options2.redirectUri);
|
|
66
|
+
url2.search = new URLSearchParams(e.data).toString();
|
|
67
|
+
window.location.href = url2.toString();
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
return {
|
|
72
|
+
id: "ding-zj",
|
|
73
|
+
name: "\u6D59\u653F\u9489\u767B\u5F55",
|
|
74
|
+
type: "oauth",
|
|
75
|
+
authorization: authorization[options.mode],
|
|
76
|
+
callbackUrl: "/bs/loginByDingZJ",
|
|
77
|
+
initQRCode: options.mode === "embed" ? initQRCode : void 0,
|
|
78
|
+
...options
|
|
79
|
+
};
|
|
80
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { P as ProviderUserConfig, c as ProviderConfig } from '../interface-C_qnbvmk.cjs';
|
|
2
|
+
import 'vue-router';
|
|
3
|
+
|
|
4
|
+
interface DingZJConfig extends ProviderUserConfig {
|
|
5
|
+
/**
|
|
6
|
+
* 登录方式
|
|
7
|
+
* - `redirect` 跳转浙政钉的扫码页面
|
|
8
|
+
* - `embed` 内嵌浙政钉的登录二维码
|
|
9
|
+
*/
|
|
10
|
+
mode: 'redirect' | 'embed';
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 浙政钉扫码登录
|
|
14
|
+
*/
|
|
15
|
+
declare function DingZJ(options: DingZJConfig): ProviderConfig;
|
|
16
|
+
|
|
17
|
+
export { DingZJ as default };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { P as ProviderUserConfig, c as ProviderConfig } from '../interface-C_qnbvmk.js';
|
|
2
|
+
import 'vue-router';
|
|
3
|
+
|
|
4
|
+
interface DingZJConfig extends ProviderUserConfig {
|
|
5
|
+
/**
|
|
6
|
+
* 登录方式
|
|
7
|
+
* - `redirect` 跳转浙政钉的扫码页面
|
|
8
|
+
* - `embed` 内嵌浙政钉的登录二维码
|
|
9
|
+
*/
|
|
10
|
+
mode: 'redirect' | 'embed';
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 浙政钉扫码登录
|
|
14
|
+
*/
|
|
15
|
+
declare function DingZJ(options: DingZJConfig): ProviderConfig;
|
|
16
|
+
|
|
17
|
+
export { DingZJ as default };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// src/providers/ding-zj.ts
|
|
2
|
+
function DingZJ(options) {
|
|
3
|
+
const { clientId, redirectUri } = options;
|
|
4
|
+
const authorization = {
|
|
5
|
+
/** 跳转外部页面 */
|
|
6
|
+
redirect: {
|
|
7
|
+
url: "https://openplatform-pro.ding.zj.gov.cn/oauth2/auth.htm",
|
|
8
|
+
params: {
|
|
9
|
+
response_type: "code",
|
|
10
|
+
client_id: clientId,
|
|
11
|
+
redirect_uri: redirectUri,
|
|
12
|
+
scope: "get_user_info",
|
|
13
|
+
authType: "QRCODE"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
/** 内嵌二维码 */
|
|
17
|
+
embed: {
|
|
18
|
+
url: "https://login-pro.ding.zj.gov.cn/oauth2/auth.htm",
|
|
19
|
+
params: {
|
|
20
|
+
response_type: "code",
|
|
21
|
+
client_id: clientId,
|
|
22
|
+
redirect_uri: redirectUri,
|
|
23
|
+
scope: "get_user_info",
|
|
24
|
+
authType: "QRCODE",
|
|
25
|
+
embedMode: "true"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const initQRCode = (url, options2) => {
|
|
30
|
+
const target = document.getElementById(options2.id);
|
|
31
|
+
if (!target) {
|
|
32
|
+
throw new Error(`\u672A\u627E\u5230id\u4E3A${options2.id}\u7684DOM\u5143\u7D20`);
|
|
33
|
+
}
|
|
34
|
+
const iframe = document.createElement("iframe");
|
|
35
|
+
iframe.src = url;
|
|
36
|
+
iframe.width = "200";
|
|
37
|
+
iframe.height = "200";
|
|
38
|
+
document.appendChild(iframe);
|
|
39
|
+
window.addEventListener("message", (e) => {
|
|
40
|
+
if (options2.redirectUri) {
|
|
41
|
+
const url2 = new URL(options2.redirectUri);
|
|
42
|
+
url2.search = new URLSearchParams(e.data).toString();
|
|
43
|
+
window.location.href = url2.toString();
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
return {
|
|
48
|
+
id: "ding-zj",
|
|
49
|
+
name: "\u6D59\u653F\u9489\u767B\u5F55",
|
|
50
|
+
type: "oauth",
|
|
51
|
+
authorization: authorization[options.mode],
|
|
52
|
+
callbackUrl: "/bs/loginByDingZJ",
|
|
53
|
+
initQRCode: options.mode === "embed" ? initQRCode : void 0,
|
|
54
|
+
...options
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export {
|
|
58
|
+
DingZJ as default
|
|
59
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pubinfo/module-auth",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "2.0.0-beta.14",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"default": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"./providers/*": {
|
|
11
|
+
"types": "./dist/providers/*.d.ts",
|
|
12
|
+
"default": "./dist/providers/*.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"main": "./dist/index.js",
|
|
16
|
+
"module": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"src"
|
|
21
|
+
],
|
|
22
|
+
"peerDependencies": {
|
|
23
|
+
"pubinfo": "2.0.0-beta.14"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"tsup": "^8.4.0",
|
|
27
|
+
"pubinfo": "2.0.0-beta.14"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"dev": "tsup --watch src",
|
|
31
|
+
"build": "tsup"
|
|
32
|
+
}
|
|
33
|
+
}
|
package/src/core.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type { AuthConfig, ProviderUserConfig, Recordable, ThirdParty } from './interface';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 初始化
|
|
5
|
+
* @param config 初始化配置
|
|
6
|
+
*/
|
|
7
|
+
export function createAuth(config: AuthConfig = {}) {
|
|
8
|
+
const {
|
|
9
|
+
baseURL = '',
|
|
10
|
+
providers = [],
|
|
11
|
+
} = config;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 获取指定的 `Provider`
|
|
15
|
+
* @param id
|
|
16
|
+
*/
|
|
17
|
+
function getProvider(id?: ThirdParty) {
|
|
18
|
+
const provider = id ? providers.find(provider => provider.id === id) : providers[0];
|
|
19
|
+
if (!provider) {
|
|
20
|
+
throw new Error(`Provider '${id}' is not found.`);
|
|
21
|
+
}
|
|
22
|
+
return provider;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
/**
|
|
27
|
+
* 前往登录
|
|
28
|
+
* @param id 唯一值
|
|
29
|
+
* @param options 登录时需要传递的参数
|
|
30
|
+
*/
|
|
31
|
+
async signIn(id: ThirdParty, options?: Recordable) {
|
|
32
|
+
const provider = getProvider(id);
|
|
33
|
+
const { type, authorization } = provider;
|
|
34
|
+
|
|
35
|
+
if (typeof authorization === 'function') {
|
|
36
|
+
return await authorization(options);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (type === 'oauth' || type === 'custom') {
|
|
40
|
+
const url = createUrl(provider);
|
|
41
|
+
window.location.replace(url);
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 生成二维码
|
|
47
|
+
* @param id 第三方的唯一值
|
|
48
|
+
* @param options 生成二维码需要传递的参数
|
|
49
|
+
* @param options.id `getElementById`中指定的`id`
|
|
50
|
+
*/
|
|
51
|
+
renderQRCode(id: ThirdParty, options: { id: string } & Recordable) {
|
|
52
|
+
const provider = getProvider(id);
|
|
53
|
+
const { type, initQRCode } = provider;
|
|
54
|
+
|
|
55
|
+
if (type === 'oauth' || type === 'custom') {
|
|
56
|
+
const url = createUrl(provider);
|
|
57
|
+
initQRCode?.(url, options);
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 认证
|
|
63
|
+
* @param id 第三方的唯一值
|
|
64
|
+
*/
|
|
65
|
+
async authentication(id: ThirdParty) {
|
|
66
|
+
const provider = getProvider(id);
|
|
67
|
+
const { type, callbackUrl } = provider;
|
|
68
|
+
|
|
69
|
+
// TODO 处理hash路由中的#
|
|
70
|
+
// 获取URL上的参数
|
|
71
|
+
const qs = window.location.href.split('?')?.[1] ?? '';
|
|
72
|
+
const params = new URLSearchParams(qs);
|
|
73
|
+
|
|
74
|
+
if (typeof callbackUrl === 'function') {
|
|
75
|
+
return await callbackUrl(Object.fromEntries(params.entries()), baseURL);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (type === 'oauth' || type === 'cas' || type === 'custom') {
|
|
79
|
+
const response = await fetch(`${baseURL}${callbackUrl}?${params.toString()}`);
|
|
80
|
+
return await response.json();
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* 重定向至统一登录页
|
|
86
|
+
*/
|
|
87
|
+
redirect() {
|
|
88
|
+
const provider = providers.find(provider => provider.type === 'cas');
|
|
89
|
+
if (!provider) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const url = createUrl(provider);
|
|
94
|
+
window.location.replace(url);
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* 构建第三方授权登录地址
|
|
101
|
+
* @param provider
|
|
102
|
+
*/
|
|
103
|
+
function createUrl(provider: ProviderUserConfig) {
|
|
104
|
+
const { authorization } = provider;
|
|
105
|
+
|
|
106
|
+
if (typeof authorization === 'function') {
|
|
107
|
+
return '';
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const url = new URL(authorization?.url ?? '');
|
|
111
|
+
const params = new URLSearchParams(authorization?.params ?? {});
|
|
112
|
+
|
|
113
|
+
return `${url.toString()}?${params.toString()}`;
|
|
114
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { ModuleOptions } from 'pubinfo';
|
|
2
|
+
import type { RouteRecordRaw } from 'vue-router';
|
|
3
|
+
import type { AuthOptions } from './interface';
|
|
4
|
+
import { cleanup } from 'pubinfo';
|
|
5
|
+
import { createAuth as create } from './core';
|
|
6
|
+
import { Auth } from './pages/auth';
|
|
7
|
+
|
|
8
|
+
export function createAuth(options: AuthOptions = {}) {
|
|
9
|
+
const { redirectTo } = options;
|
|
10
|
+
const { signIn, renderQRCode, authentication, redirect } = create(options);
|
|
11
|
+
|
|
12
|
+
function auth(): ModuleOptions {
|
|
13
|
+
return {
|
|
14
|
+
name: 'pubinfo:auth',
|
|
15
|
+
enforce: 'pre',
|
|
16
|
+
setup(ctx) {
|
|
17
|
+
const { router } = ctx;
|
|
18
|
+
|
|
19
|
+
const ROUTE_AUTH: RouteRecordRaw = {
|
|
20
|
+
path: '/auth/:type',
|
|
21
|
+
name: 'Auth',
|
|
22
|
+
component: Auth,
|
|
23
|
+
meta: {
|
|
24
|
+
whiteList: true,
|
|
25
|
+
title: '授权登录',
|
|
26
|
+
},
|
|
27
|
+
props: (route) => ({
|
|
28
|
+
type: route.params.type,
|
|
29
|
+
redirectTo() {
|
|
30
|
+
router.push(redirectTo ?? '/');
|
|
31
|
+
},
|
|
32
|
+
authentication,
|
|
33
|
+
}),
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
router.beforeEach(to => {
|
|
37
|
+
// 注册静态页面
|
|
38
|
+
if (!router.hasRoute(ROUTE_AUTH.name!)) {
|
|
39
|
+
router.addRoute(ROUTE_AUTH);
|
|
40
|
+
return to.fullPath;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// 前往单点登录前,清空登录状态
|
|
44
|
+
if (to.name === ROUTE_AUTH.name) {
|
|
45
|
+
cleanup();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// 前往登录前,重定向至统一登录页(若有)
|
|
49
|
+
if (to.name === 'Login') {
|
|
50
|
+
redirect();
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
/**
|
|
59
|
+
* 前往登录
|
|
60
|
+
* @param id 唯一值
|
|
61
|
+
* @param options 登录时需要传递的参数
|
|
62
|
+
*/
|
|
63
|
+
signIn,
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* 生成二维码
|
|
67
|
+
* @param id 第三方的唯一值
|
|
68
|
+
* @param options 生成二维码需要传递的参数
|
|
69
|
+
* @param options.id `getElementById`中指定的`id`
|
|
70
|
+
*/
|
|
71
|
+
renderQRCode,
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* 认证
|
|
75
|
+
* @param id 第三方的唯一值
|
|
76
|
+
*/
|
|
77
|
+
authentication,
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* 模块配置
|
|
81
|
+
*/
|
|
82
|
+
auth,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export * from './interface';
|
package/src/interface.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { RouteLocationRaw } from 'vue-router';
|
|
2
|
+
|
|
3
|
+
export type Recordable = Record<string, any>;
|
|
4
|
+
export type Fn<T = any, K = any> = (params?: Recordable & T) => Promise<K> | K;
|
|
5
|
+
export type FnApi<T = any> = (params: Recordable & T, baseURL: string) => Promise<any>;
|
|
6
|
+
|
|
7
|
+
export interface AuthOptions extends AuthConfig {
|
|
8
|
+
/** 登录后重定向至 */
|
|
9
|
+
redirectTo?: RouteLocationRaw
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface AuthConfig {
|
|
13
|
+
/** 接口的baseURL */
|
|
14
|
+
baseURL?: string
|
|
15
|
+
|
|
16
|
+
providers?: ProviderConfig[]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** 第三方类型 */
|
|
20
|
+
export type ThirdParty = string;
|
|
21
|
+
export type ProviderUserConfig = Partial<ProviderConfig>;
|
|
22
|
+
|
|
23
|
+
export interface ProviderConfig {
|
|
24
|
+
/** 唯一值 */
|
|
25
|
+
id: string
|
|
26
|
+
|
|
27
|
+
/** 名称 */
|
|
28
|
+
name: string
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 协议类型
|
|
32
|
+
* - `oauth` 第三方授权登录
|
|
33
|
+
* - `cas` 统一账号登录
|
|
34
|
+
* - `custom` 自定义
|
|
35
|
+
*/
|
|
36
|
+
type: 'oauth' | 'cas' | 'custom'
|
|
37
|
+
|
|
38
|
+
/** 授权登录地址 */
|
|
39
|
+
authorization?: Authorization | Fn
|
|
40
|
+
|
|
41
|
+
/** `client_id` */
|
|
42
|
+
clientId?: string
|
|
43
|
+
|
|
44
|
+
/** `redirect_uri` */
|
|
45
|
+
redirectUri?: string
|
|
46
|
+
|
|
47
|
+
/** 授权登录接口 */
|
|
48
|
+
callbackUrl?: string | FnApi
|
|
49
|
+
|
|
50
|
+
/** 初始化二维码 */
|
|
51
|
+
initQRCode?: (url: string, params: { id: string } & Recordable) => Promise<void> | void
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface Authorization {
|
|
55
|
+
/** 授权登录地址 */
|
|
56
|
+
url: string
|
|
57
|
+
|
|
58
|
+
/** 授权登录参数 */
|
|
59
|
+
params?: Recordable
|
|
60
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { useUserStore } from 'pubinfo';
|
|
2
|
+
import { defineComponent, h, onMounted, ref } from 'vue';
|
|
3
|
+
|
|
4
|
+
export const Auth = defineComponent({
|
|
5
|
+
props: {
|
|
6
|
+
type: String,
|
|
7
|
+
redirectTo: Function,
|
|
8
|
+
authentication: Function,
|
|
9
|
+
},
|
|
10
|
+
setup(props) {
|
|
11
|
+
const userStore = useUserStore();
|
|
12
|
+
|
|
13
|
+
const message = ref('授权登录中...');
|
|
14
|
+
|
|
15
|
+
onMounted(async () => {
|
|
16
|
+
const res = await props.authentication?.(props.type);
|
|
17
|
+
if (res?.success) {
|
|
18
|
+
userStore.setToken(res?.data?.accessToken, res?.data?.refreshToken);
|
|
19
|
+
props?.redirectTo?.();
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
message.value = res?.msg ?? res?.message;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
return () => {
|
|
27
|
+
return h(
|
|
28
|
+
'div',
|
|
29
|
+
{
|
|
30
|
+
style: {
|
|
31
|
+
display: 'flex',
|
|
32
|
+
justifyContent: 'center',
|
|
33
|
+
alignItems: 'center',
|
|
34
|
+
width: '100vw',
|
|
35
|
+
height: '100vh',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
message.value,
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
},
|
|
42
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ProviderConfig, ProviderUserConfig } from '../interface';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 4A登录
|
|
5
|
+
*/
|
|
6
|
+
export default function FourA(options: ProviderUserConfig): ProviderConfig {
|
|
7
|
+
const { clientId, redirectUri } = options;
|
|
8
|
+
|
|
9
|
+
return {
|
|
10
|
+
id: '4A',
|
|
11
|
+
name: '4A登录',
|
|
12
|
+
type: 'oauth',
|
|
13
|
+
authorization: {
|
|
14
|
+
url: 'http://134.108.76.137:7001/index',
|
|
15
|
+
params: {
|
|
16
|
+
response_type: 'code',
|
|
17
|
+
client_id: clientId,
|
|
18
|
+
redirect_uri: redirectUri,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
callbackUrl: '/bs/loginBy4a',
|
|
22
|
+
...options,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Fn, ProviderConfig } from '../interface';
|
|
2
|
+
|
|
3
|
+
interface CredentialsConfig {
|
|
4
|
+
authorize: Fn<any>
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 凭证登录
|
|
9
|
+
*/
|
|
10
|
+
export default function Credentials(options: CredentialsConfig): ProviderConfig {
|
|
11
|
+
const { authorize } = options;
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
id: 'credentials',
|
|
15
|
+
name: '凭证登录',
|
|
16
|
+
type: 'custom',
|
|
17
|
+
authorization: authorize,
|
|
18
|
+
};
|
|
19
|
+
}
|