@midwayjs/passport 2.13.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 +275 -0
- package/dist/config/config.default.d.ts +5 -0
- package/dist/config/config.default.js +8 -0
- package/dist/configuration.d.ts +5 -0
- package/dist/configuration.js +29 -0
- package/dist/decorator/strategy.d.ts +2 -0
- package/dist/decorator/strategy.js +12 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +18 -0
- package/dist/interface.d.ts +20 -0
- package/dist/interface.js +10 -0
- package/dist/service/passport.d.ts +13 -0
- package/dist/service/passport.js +252 -0
- package/dist/util.d.ts +3 -0
- package/dist/util.js +14 -0
- package/package.json +40 -0
package/README.md
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# @midwayjs/passport
|
|
2
|
+
|
|
3
|
+
身份验证是大多数Web应用程序的重要组成部分。因此Midway封装了目前Nodejs中最流行的Passport库。
|
|
4
|
+
Passport是通过称为策略的可扩展插件进行身份验证请求。Passport 不挂载路由或假设任何特定的数据库,这最大限度地提高了灵活性并允许开发人员做出应用程序级别的决策。
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
## 准备
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
1. 安装 `npm i @midwayjs/passport`
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
$ npm i passport --save
|
|
16
|
+
$ npm i @types/passport --save-dev
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
2. 如果有需要的话,开启相对应框架的 bodyparser,session
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## 使用
|
|
23
|
+
|
|
24
|
+
这里我们以本地认证,和Jwt作为演示。
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
首先
|
|
28
|
+
```bash
|
|
29
|
+
// configuration.ts
|
|
30
|
+
|
|
31
|
+
import { join } from 'path';
|
|
32
|
+
import * as jwt from '@midwayjs/jwt';
|
|
33
|
+
import { ILifeCycle,} from '@midwayjs/core';
|
|
34
|
+
import { Configuration } from '@midwayjs/decorator';
|
|
35
|
+
import * as passport from '@midwayjs/passport';
|
|
36
|
+
|
|
37
|
+
@Configuration({
|
|
38
|
+
imports: [
|
|
39
|
+
jwt,
|
|
40
|
+
passport,
|
|
41
|
+
],
|
|
42
|
+
importConfigs: [join(__dirname, './config')],
|
|
43
|
+
conflictCheck: true,
|
|
44
|
+
})
|
|
45
|
+
export class ContainerLifeCycle implements ILifeCycle {}
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
### e.g. 本地
|
|
49
|
+
我们可以通过`@CuustomStrategy`和派生`PassportStrategy`来自启动一个策略。通过 validate 钩子来获取有效负载,并且此函数必须有返回值,其参数并不明确,可以参考对应的Strategy或者通过展开符打印查看。
|
|
50
|
+
```typescript
|
|
51
|
+
// local-strategy.ts
|
|
52
|
+
|
|
53
|
+
import { CustomStrategy, PassportStrategy } from '@midwayjs/passport';
|
|
54
|
+
import { Repository } from 'typeorm';
|
|
55
|
+
import { InjectEntityModel } from '@midwayjs/orm';
|
|
56
|
+
import { UserEntity } from './user';
|
|
57
|
+
import * as bcrypt from 'bcrypt';
|
|
58
|
+
|
|
59
|
+
@CustomStrategy()
|
|
60
|
+
export class LocalStrategy extends PassportStrategy(Strategy) {
|
|
61
|
+
@InjectEntityModel(UserEntity)
|
|
62
|
+
userModel: Repository<UserEntity>;
|
|
63
|
+
|
|
64
|
+
// 策略的验证
|
|
65
|
+
async validate(username, password) {
|
|
66
|
+
const user = await this.userModel.findOne({ username });
|
|
67
|
+
if (await bcrypt.compare(password, user.password)) {
|
|
68
|
+
throw new Error('error password ' + username);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
username,
|
|
73
|
+
password,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// 当前策略的参数
|
|
78
|
+
getStrategyOptions(): any {
|
|
79
|
+
return {};
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
使用派生`PassportMiddleware`出一个中间件。
|
|
85
|
+
```typescript
|
|
86
|
+
// local-middleware.ts
|
|
87
|
+
|
|
88
|
+
import { Inject, Provide } from '@midwayjs/decorator';
|
|
89
|
+
import { PassportMiddleware } from '@midwayjs/passport';
|
|
90
|
+
import { Context } from '@midwayjs/express';
|
|
91
|
+
|
|
92
|
+
@Provide('local') // 此处可以使用一个简短的identifier
|
|
93
|
+
export class LocalPassportMiddleware extends PassportMiddleware(LocalStrategy) {
|
|
94
|
+
// 设置 AuthenticateOptions
|
|
95
|
+
getAuthenticateOptions(): Promise<passport.AuthenticateOptions> | passport.AuthenticateOptions {
|
|
96
|
+
return {
|
|
97
|
+
failureRedirect: '/login',
|
|
98
|
+
presetProperty: 'user'
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
```typescript
|
|
104
|
+
// controller.ts
|
|
105
|
+
|
|
106
|
+
import { Provide, Post, Inject, Controller } from '@midwayjs/decorator';
|
|
107
|
+
|
|
108
|
+
@Provide()
|
|
109
|
+
@Controller('/')
|
|
110
|
+
export class LocalController {
|
|
111
|
+
|
|
112
|
+
@Post('/passport/local', { middleware: ['local'] })
|
|
113
|
+
async localPassport() {
|
|
114
|
+
console.log('local user: ', this.ctx.req.user);
|
|
115
|
+
return this.ctx.req.user;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
使用curl 模拟一次请求。
|
|
120
|
+
```bash
|
|
121
|
+
curl -X POST http://localhost:7001/passport/local -d '{"username": "demo", "password": "1234"}' -H "Content-Type: application/json"
|
|
122
|
+
|
|
123
|
+
结果 {"username": "demo", "password": "1234"}
|
|
124
|
+
```
|
|
125
|
+
### e.g. Jwt
|
|
126
|
+
首先你需要安装`npm i @midwayjs/jwt`,然后在 config.ts 中配置。PS. 默认未加密,请不要吧敏感信息存放在payload中。
|
|
127
|
+
```typescript
|
|
128
|
+
export const jwt = {
|
|
129
|
+
secret: 'xxxxxxxxxxxxxx', // fs.readFileSync('xxxxx.key')
|
|
130
|
+
expiresIn: '2d' // https://github.com/vercel/ms
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
```typescript
|
|
134
|
+
// strategy/jwt-strategy.ts
|
|
135
|
+
|
|
136
|
+
import { CustomStrategy, PassportStrategy } from '@midwayjs/passport';
|
|
137
|
+
import { Strategy, ExtractJwt } from 'passport-jwt';
|
|
138
|
+
|
|
139
|
+
@CustomStrategy()
|
|
140
|
+
export class JwtStrategy extends PassportStrategy(
|
|
141
|
+
Strategy,
|
|
142
|
+
'jwt'
|
|
143
|
+
) {
|
|
144
|
+
@Config('jwt')
|
|
145
|
+
jwtConfig;
|
|
146
|
+
|
|
147
|
+
async validate(payload) {
|
|
148
|
+
return payload;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
getStrategyOptions(): any {
|
|
152
|
+
return {
|
|
153
|
+
secretOrKey: this.jwtConfig.secret,
|
|
154
|
+
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
```typescript
|
|
162
|
+
// jwt-middleware.ts
|
|
163
|
+
|
|
164
|
+
import { Provide } from '@midwayjs/decorator';
|
|
165
|
+
import { PassportMiddleware } from '@midwayjs/passport';
|
|
166
|
+
import { JwtStrategy } from './strategy/jwt-strategy';
|
|
167
|
+
|
|
168
|
+
@Provide()
|
|
169
|
+
export class JwtPassportMiddleware extends PassportMiddleware(JwtStrategy) {
|
|
170
|
+
getAuthenticateOptions(): Promise<passport.AuthenticateOptions> | passport.AuthenticateOptions {
|
|
171
|
+
return {};
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
```typescript
|
|
177
|
+
import { Provide, Post, Inject } from '@midwayjs/decorator';
|
|
178
|
+
import { Controller, Post } from '@midwayjs/decorator';
|
|
179
|
+
import { Jwt } from '@midwayjs/jwt';
|
|
180
|
+
|
|
181
|
+
@Provide()
|
|
182
|
+
@Controller('/')
|
|
183
|
+
export class JwtController {
|
|
184
|
+
|
|
185
|
+
@Inject()
|
|
186
|
+
jwt: Jwt;
|
|
187
|
+
|
|
188
|
+
@Inject()
|
|
189
|
+
ctx: any;
|
|
190
|
+
|
|
191
|
+
@Post('/passport/jwt', { middleware: ['jwtPassportMiddleware'] })
|
|
192
|
+
async jwtPassport() {
|
|
193
|
+
console.log('jwt user: ', this.ctx.req.user);
|
|
194
|
+
return this.ctx.req.user;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
@Post('/jwt')
|
|
198
|
+
async genJwt() {
|
|
199
|
+
return {
|
|
200
|
+
t: await this.jwt.sign({ msg: 'Hello Midway' }),
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
使用curl模拟请求
|
|
206
|
+
```bash
|
|
207
|
+
curl -X POST http://127.0.0.1:7001/jwt
|
|
208
|
+
|
|
209
|
+
结果 {"t": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}
|
|
210
|
+
|
|
211
|
+
curl http://127.0.0.1:7001/passport/jwt -H "Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|
212
|
+
|
|
213
|
+
结果 {"msg": "Hello Midway","iat": 1635468727,"exp": 1635468827}
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
## 自定义其他策略
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
`@midwayjs/passport`支持自定义[其他策略](http://www.passportjs.org/packages/),这里以github oauth为例。
|
|
220
|
+
首先 `npm i passport-github`,之后编写如下代码:
|
|
221
|
+
```typescript
|
|
222
|
+
// github-strategy.ts
|
|
223
|
+
|
|
224
|
+
import { CustomStrategy, PassportStrategy } from '@midwayjs/passport';
|
|
225
|
+
import { Strategy, StrategyOptions } from 'passport-github';
|
|
226
|
+
|
|
227
|
+
const GITHUB_CLIENT_ID = 'xxxxxx', GITHUB_CLIENT_SECRET = 'xxxxxxxx';
|
|
228
|
+
|
|
229
|
+
@CustomStrategy()
|
|
230
|
+
export class GithubStrategy extends PassportStrategy(Strategy, 'github') {
|
|
231
|
+
async validate(...payload) {
|
|
232
|
+
return payload;
|
|
233
|
+
}
|
|
234
|
+
getStrategyOptions() {
|
|
235
|
+
return {
|
|
236
|
+
clientID: GITHUB_CLIENT_ID,
|
|
237
|
+
clientSecret: GITHUB_CLIENT_SECRET,
|
|
238
|
+
callbackURL: 'https://127.0.0.1:7001/auth/github/cb'
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
```
|
|
244
|
+
```typescript
|
|
245
|
+
// github-middleware.ts
|
|
246
|
+
|
|
247
|
+
import { PassportMiddleware } from '@midwayjs/passport';
|
|
248
|
+
|
|
249
|
+
@Provide()
|
|
250
|
+
export class GithubPassportMiddleware extends PassportMiddleware {
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
```typescript
|
|
254
|
+
// controller.ts
|
|
255
|
+
|
|
256
|
+
import { Provide, Get, Inject } from '@midwayjs/decorator';
|
|
257
|
+
|
|
258
|
+
@Provide()
|
|
259
|
+
@Controller('/oauth')
|
|
260
|
+
export class AuthController {
|
|
261
|
+
@Inject()
|
|
262
|
+
ctx: any;
|
|
263
|
+
|
|
264
|
+
@Get('/github', { middleware: ['githubPassportMiddleware'] })
|
|
265
|
+
async githubOAuth() {}
|
|
266
|
+
|
|
267
|
+
@Get('/github/cb', { middleware: ['githubPassportMiddleware'] })
|
|
268
|
+
async githubOAuthCallback() {
|
|
269
|
+
return this.ctx.req.user;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ILifeCycle, IMidwayApplication, IMidwayContainer } from '@midwayjs/core';
|
|
2
|
+
export declare class PassportConfiguration implements ILifeCycle {
|
|
3
|
+
onReady(container: IMidwayContainer, app: IMidwayApplication): Promise<void>;
|
|
4
|
+
}
|
|
5
|
+
//# sourceMappingURL=configuration.d.ts.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.PassportConfiguration = void 0;
|
|
10
|
+
const decorator_1 = require("@midwayjs/decorator");
|
|
11
|
+
const DefaultConfig = require("./config/config.default");
|
|
12
|
+
const passport_1 = require("./service/passport");
|
|
13
|
+
let PassportConfiguration = class PassportConfiguration {
|
|
14
|
+
async onReady(container, app) {
|
|
15
|
+
await container.getAsync(passport_1.PassportService);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
PassportConfiguration = __decorate([
|
|
19
|
+
(0, decorator_1.Configuration)({
|
|
20
|
+
namespace: 'passport',
|
|
21
|
+
importConfigs: [
|
|
22
|
+
{
|
|
23
|
+
default: DefaultConfig,
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
})
|
|
27
|
+
], PassportConfiguration);
|
|
28
|
+
exports.PassportConfiguration = PassportConfiguration;
|
|
29
|
+
//# sourceMappingURL=configuration.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CustomStrategy = void 0;
|
|
4
|
+
const decorator_1 = require("@midwayjs/decorator");
|
|
5
|
+
function CustomStrategy() {
|
|
6
|
+
return target => {
|
|
7
|
+
(0, decorator_1.Scope)(decorator_1.ScopeEnum.Singleton)(target);
|
|
8
|
+
(0, decorator_1.Provide)()(target);
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
exports.CustomStrategy = CustomStrategy;
|
|
12
|
+
//# sourceMappingURL=strategy.js.map
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.Configuration = void 0;
|
|
14
|
+
var configuration_1 = require("./configuration");
|
|
15
|
+
Object.defineProperty(exports, "Configuration", { enumerable: true, get: function () { return configuration_1.PassportConfiguration; } });
|
|
16
|
+
__exportStar(require("./decorator/strategy"), exports);
|
|
17
|
+
__exportStar(require("./service/passport"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as passport from 'passport';
|
|
2
|
+
export interface IPassportStrategy {
|
|
3
|
+
validate(...args: any[]): any;
|
|
4
|
+
getStrategyOptions(): any;
|
|
5
|
+
serializeUser?(user: any, done: (err: any, id?: any) => void): void;
|
|
6
|
+
deserializeUser?(id: any, done: (err: any, user?: any) => void): void;
|
|
7
|
+
transformAuthInfo?(info: any, done: (err: any, info: any) => void): void;
|
|
8
|
+
}
|
|
9
|
+
export declare abstract class AbstractStrategy implements IPassportStrategy {
|
|
10
|
+
abstract validate(...args: any[]): any;
|
|
11
|
+
abstract getStrategyOptions(): any;
|
|
12
|
+
}
|
|
13
|
+
export interface IPassportMiddleware {
|
|
14
|
+
authenticate?(options: passport.AuthenticateOptions, callback: Function): any;
|
|
15
|
+
}
|
|
16
|
+
export declare abstract class AbstractPassportMiddleware implements IPassportMiddleware {
|
|
17
|
+
abstract getAuthenticateOptions(): Promise<passport.AuthenticateOptions> | passport.AuthenticateOptions;
|
|
18
|
+
authenticate?(options: passport.AuthenticateOptions, callback?: Function): any;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=interface.d.ts.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AbstractPassportMiddleware = exports.AbstractStrategy = void 0;
|
|
4
|
+
class AbstractStrategy {
|
|
5
|
+
}
|
|
6
|
+
exports.AbstractStrategy = AbstractStrategy;
|
|
7
|
+
class AbstractPassportMiddleware {
|
|
8
|
+
}
|
|
9
|
+
exports.AbstractPassportMiddleware = AbstractPassportMiddleware;
|
|
10
|
+
//# sourceMappingURL=interface.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as passport from 'passport';
|
|
2
|
+
import { AbstractPassportMiddleware, AbstractStrategy } from '../interface';
|
|
3
|
+
export declare function PassportStrategy(Strategy: new (...args: any[]) => passport.Strategy, name?: string): new (...args: any[]) => AbstractStrategy;
|
|
4
|
+
export declare type StrategyClass = new (...args: any[]) => AbstractStrategy;
|
|
5
|
+
export declare function PassportMiddleware(type: StrategyClass | StrategyClass[]): new (...args: any[]) => AbstractPassportMiddleware;
|
|
6
|
+
export declare class PassportService {
|
|
7
|
+
passportConfig: any;
|
|
8
|
+
app: any;
|
|
9
|
+
inited: boolean;
|
|
10
|
+
initMiddleware(): void;
|
|
11
|
+
authenticate(strategy: StrategyClass | StrategyClass[], options: passport.AuthenticateOptions): any;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=passport.d.ts.map
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.PassportService = exports.PassportMiddleware = exports.PassportStrategy = void 0;
|
|
13
|
+
const decorator_1 = require("@midwayjs/decorator");
|
|
14
|
+
const util_1 = require("../util");
|
|
15
|
+
const interface_1 = require("../interface");
|
|
16
|
+
function PassportStrategy(Strategy, name) {
|
|
17
|
+
class InnerStrategyAbstractClass extends interface_1.AbstractStrategy {
|
|
18
|
+
constructor() {
|
|
19
|
+
super(...arguments);
|
|
20
|
+
this.inited = false;
|
|
21
|
+
}
|
|
22
|
+
async initStrategy() {
|
|
23
|
+
if (!this.inited) {
|
|
24
|
+
this.inited = true;
|
|
25
|
+
const cb = async (...params) => {
|
|
26
|
+
const done = params[params.length - 1];
|
|
27
|
+
try {
|
|
28
|
+
const result = await this.validate(...params);
|
|
29
|
+
if (Array.isArray(result)) {
|
|
30
|
+
done(null, ...result);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
done(null, result);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
done(err, null);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
this.strategy = new Strategy(this.getStrategyOptions(), cb);
|
|
41
|
+
const passport = (0, util_1.getPassport)();
|
|
42
|
+
if (name) {
|
|
43
|
+
passport.use(name, this.strategy);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
passport.use(this.strategy);
|
|
47
|
+
}
|
|
48
|
+
if (this['serializeUser']) {
|
|
49
|
+
passport.serializeUser(this['serializeUser']);
|
|
50
|
+
}
|
|
51
|
+
if (this['deserializeUser']) {
|
|
52
|
+
passport.deserializeUser(this['deserializeUser']);
|
|
53
|
+
}
|
|
54
|
+
if (this['transformAuthInfo']) {
|
|
55
|
+
passport.transformAuthInfo(this['transformAuthInfo']);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
getStrategy() {
|
|
60
|
+
return this.strategy;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return InnerStrategyAbstractClass;
|
|
64
|
+
}
|
|
65
|
+
exports.PassportStrategy = PassportStrategy;
|
|
66
|
+
function PassportMiddleware(type) {
|
|
67
|
+
class InnerPassportMiddleware extends interface_1.AbstractPassportMiddleware {
|
|
68
|
+
authenticate(options) {
|
|
69
|
+
return this.passportService.authenticate(type, options);
|
|
70
|
+
}
|
|
71
|
+
resolve() {
|
|
72
|
+
this.passportService.initMiddleware();
|
|
73
|
+
if ((0, util_1.isExpressMode)()) {
|
|
74
|
+
return async (req, res, next) => {
|
|
75
|
+
return this.authenticate(await this.getAuthenticateOptions())(req, res, next);
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
return async (ctx, next) => {
|
|
80
|
+
return this.authenticate(await this.getAuthenticateOptions())(ctx, next);
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
getAuthenticateOptions() {
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
__decorate([
|
|
89
|
+
(0, decorator_1.Inject)(),
|
|
90
|
+
__metadata("design:type", PassportService)
|
|
91
|
+
], InnerPassportMiddleware.prototype, "passportService", void 0);
|
|
92
|
+
return InnerPassportMiddleware;
|
|
93
|
+
}
|
|
94
|
+
exports.PassportMiddleware = PassportMiddleware;
|
|
95
|
+
let PassportService = class PassportService {
|
|
96
|
+
constructor() {
|
|
97
|
+
this.inited = false;
|
|
98
|
+
}
|
|
99
|
+
initMiddleware() {
|
|
100
|
+
if (!this.inited) {
|
|
101
|
+
this.inited = true;
|
|
102
|
+
const passport = (0, util_1.getPassport)();
|
|
103
|
+
this.app.use(passport.initialize());
|
|
104
|
+
if (this.passportConfig.session) {
|
|
105
|
+
this.app.use(passport.session());
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
authenticate(strategy, options) {
|
|
110
|
+
if (!Array.isArray(strategy)) {
|
|
111
|
+
strategy = [strategy];
|
|
112
|
+
}
|
|
113
|
+
if ((0, util_1.isExpressMode)()) {
|
|
114
|
+
return async (req, res, next) => {
|
|
115
|
+
// merge options with default options
|
|
116
|
+
const authOptions = {
|
|
117
|
+
...this.passportConfig,
|
|
118
|
+
...options,
|
|
119
|
+
};
|
|
120
|
+
if (authOptions.session && req.session[authOptions.property]) {
|
|
121
|
+
req[authOptions.property] = req.session[authOptions.property];
|
|
122
|
+
}
|
|
123
|
+
// ignore user has exists
|
|
124
|
+
if (req[authOptions.property]) {
|
|
125
|
+
next();
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
const passport = (0, util_1.getPassport)();
|
|
129
|
+
const strategyList = [];
|
|
130
|
+
for (const strategySingle of strategy) {
|
|
131
|
+
// got strategy
|
|
132
|
+
const strategyInstance = await this.app
|
|
133
|
+
.getApplicationContext()
|
|
134
|
+
.getAsync(strategySingle);
|
|
135
|
+
await strategyInstance.initStrategy();
|
|
136
|
+
strategyList.push(strategyInstance.getStrategy());
|
|
137
|
+
}
|
|
138
|
+
const user = await new Promise((resolve, reject) => {
|
|
139
|
+
// authenticate
|
|
140
|
+
passport.authenticate(strategyList, authOptions, (err, user, info, status) => {
|
|
141
|
+
if (err) {
|
|
142
|
+
reject(err);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
resolve(user);
|
|
146
|
+
}
|
|
147
|
+
})(req, res, err => (err ? reject(err) : resolve(0)));
|
|
148
|
+
});
|
|
149
|
+
if (user) {
|
|
150
|
+
req[authOptions.property] = user;
|
|
151
|
+
if (authOptions.session) {
|
|
152
|
+
req.logIn(user, options, next);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
if (options.failureRedirect) {
|
|
158
|
+
res.redirect(options.failureRedirect);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
res.status(401);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
next();
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
return async (ctx, next) => {
|
|
171
|
+
// merge options with default options
|
|
172
|
+
const authOptions = {
|
|
173
|
+
...this.passportConfig,
|
|
174
|
+
...options,
|
|
175
|
+
};
|
|
176
|
+
if (authOptions.session &&
|
|
177
|
+
ctx.session.passport &&
|
|
178
|
+
ctx.session.passport[authOptions.property]) {
|
|
179
|
+
ctx.state[authOptions.property] =
|
|
180
|
+
ctx.session.passport[authOptions.property];
|
|
181
|
+
}
|
|
182
|
+
// ignore user has exists
|
|
183
|
+
if (ctx.state[authOptions.property]) {
|
|
184
|
+
await next();
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
const passport = (0, util_1.getPassport)();
|
|
188
|
+
const strategyList = [];
|
|
189
|
+
for (const strategySingle of strategy) {
|
|
190
|
+
// got strategy
|
|
191
|
+
const strategyInstance = await this.app
|
|
192
|
+
.getApplicationContext()
|
|
193
|
+
.getAsync(strategySingle);
|
|
194
|
+
await strategyInstance.initStrategy();
|
|
195
|
+
strategyList.push(strategyInstance.getStrategy());
|
|
196
|
+
}
|
|
197
|
+
try {
|
|
198
|
+
const user = await new Promise((resolve, reject) => {
|
|
199
|
+
// authenticate
|
|
200
|
+
passport.authenticate(strategyList, authOptions, (err, user, info, status) => {
|
|
201
|
+
if (err) {
|
|
202
|
+
reject(err);
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
resolve(user);
|
|
206
|
+
}
|
|
207
|
+
})(ctx, err => (err ? reject(err) : resolve(0)));
|
|
208
|
+
});
|
|
209
|
+
if (user) {
|
|
210
|
+
ctx.state[authOptions.property] = user;
|
|
211
|
+
if (authOptions.session) {
|
|
212
|
+
// save to ctx.session.passport
|
|
213
|
+
await ctx.login(user, options);
|
|
214
|
+
}
|
|
215
|
+
if (options.successRedirect) {
|
|
216
|
+
ctx.redirect(options.successRedirect);
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
if (options.failureRedirect) {
|
|
222
|
+
ctx.redirect(options.failureRedirect);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
ctx.status = 401;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
await next();
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
ctx.throw(err);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
__decorate([
|
|
240
|
+
(0, decorator_1.Config)('passport'),
|
|
241
|
+
__metadata("design:type", Object)
|
|
242
|
+
], PassportService.prototype, "passportConfig", void 0);
|
|
243
|
+
__decorate([
|
|
244
|
+
(0, decorator_1.App)(),
|
|
245
|
+
__metadata("design:type", Object)
|
|
246
|
+
], PassportService.prototype, "app", void 0);
|
|
247
|
+
PassportService = __decorate([
|
|
248
|
+
(0, decorator_1.Provide)(),
|
|
249
|
+
(0, decorator_1.Scope)(decorator_1.ScopeEnum.Singleton)
|
|
250
|
+
], PassportService);
|
|
251
|
+
exports.PassportService = PassportService;
|
|
252
|
+
//# sourceMappingURL=passport.js.map
|
package/dist/util.d.ts
ADDED
package/dist/util.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isExpressMode = exports.getPassport = void 0;
|
|
4
|
+
const core_1 = require("@midwayjs/core");
|
|
5
|
+
function getPassport() {
|
|
6
|
+
return isExpressMode() ? require('passport') : require('./proxy/index');
|
|
7
|
+
}
|
|
8
|
+
exports.getPassport = getPassport;
|
|
9
|
+
function isExpressMode() {
|
|
10
|
+
var _a;
|
|
11
|
+
return !!((_a = process.env['MIDWAY_PASSPORT_MODE'] === 'express') !== null && _a !== void 0 ? _a : (0, core_1.safeRequire)('@midwayjs/express'));
|
|
12
|
+
}
|
|
13
|
+
exports.isExpressMode = isExpressMode;
|
|
14
|
+
//# sourceMappingURL=util.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@midwayjs/passport",
|
|
3
|
+
"description": "midway passport component",
|
|
4
|
+
"version": "2.13.3",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"typings": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist/**/*.js",
|
|
9
|
+
"dist/**/*.d.ts"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"test": "node --require=ts-node/register ../../node_modules/jest/bin/jest.js",
|
|
14
|
+
"cov": "node --require=ts-node/register ../../node_modules/.bin/jest --coverage --forceExit"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"midway",
|
|
18
|
+
"authorization",
|
|
19
|
+
"passport"
|
|
20
|
+
],
|
|
21
|
+
"author": "Nawbc",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@midwayjs/core": "^2.13.4",
|
|
25
|
+
"@midwayjs/decorator": "^2.13.2",
|
|
26
|
+
"@midwayjs/express": "^2.13.4",
|
|
27
|
+
"@midwayjs/koa": "^2.13.4",
|
|
28
|
+
"@midwayjs/mock": "^2.13.4",
|
|
29
|
+
"@midwayjs/web": "^2.13.4",
|
|
30
|
+
"@midwayjs/jwt": "^2.13.4",
|
|
31
|
+
"@types/passport": "^1.0.7",
|
|
32
|
+
"@types/passport-local": "^1.0.34",
|
|
33
|
+
"passport": "^0.5.0",
|
|
34
|
+
"passport-local": "^1.0.0",
|
|
35
|
+
"express-session": "^1.17.2"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"passport": "^0.5.0"
|
|
39
|
+
}
|
|
40
|
+
}
|