@loopback/authentication-passport 2.1.9 → 2.1.13
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/CHANGELOG.md +35 -0
- package/README.md +295 -287
- package/package.json +18 -19
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,41 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [2.1.13](https://github.com/strongloop/loopback-next/compare/@loopback/authentication-passport@2.1.12...@loopback/authentication-passport@2.1.13) (2020-08-27)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @loopback/authentication-passport
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [2.1.12](https://github.com/strongloop/loopback-next/compare/@loopback/authentication-passport@2.1.11...@loopback/authentication-passport@2.1.12) (2020-08-19)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @loopback/authentication-passport
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## [2.1.11](https://github.com/strongloop/loopback-next/compare/@loopback/authentication-passport@2.1.10...@loopback/authentication-passport@2.1.11) (2020-08-05)
|
|
23
|
+
|
|
24
|
+
**Note:** Version bump only for package @loopback/authentication-passport
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
## [2.1.10](https://github.com/strongloop/loopback-next/compare/@loopback/authentication-passport@2.1.9...@loopback/authentication-passport@2.1.10) (2020-07-20)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
### Bug Fixes
|
|
34
|
+
|
|
35
|
+
* **docs:** fix numbering ([bb9a5ae](https://github.com/strongloop/loopback-next/commit/bb9a5ae6b74018a1ec69070d5aaaf1b29ca66647))
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
6
41
|
## [2.1.9](https://github.com/strongloop/loopback-next/compare/@loopback/authentication-passport@2.1.8...@loopback/authentication-passport@2.1.9) (2020-06-30)
|
|
7
42
|
|
|
8
43
|
**Note:** Version bump only for package @loopback/authentication-passport
|
package/README.md
CHANGED
|
@@ -48,141 +48,142 @@ npm i passport-http @types/passport-http --save
|
|
|
48
48
|
|
|
49
49
|
1. Create an instance of the passport strategy
|
|
50
50
|
|
|
51
|
-
Taking the basic strategy exported from
|
|
52
|
-
[`passport-http`](https://github.com/jaredhanson/passport-http) as an
|
|
53
|
-
first create an instance of the basic strategy with your `verify`
|
|
51
|
+
Taking the basic strategy exported from
|
|
52
|
+
[`passport-http`](https://github.com/jaredhanson/passport-http) as an
|
|
53
|
+
example, first create an instance of the basic strategy with your `verify`
|
|
54
|
+
function.
|
|
54
55
|
|
|
55
|
-
```ts
|
|
56
|
-
// Create a file named `my-basic-auth-strategy.ts` to define your strategy below
|
|
56
|
+
```ts
|
|
57
|
+
// Create a file named `my-basic-auth-strategy.ts` to define your strategy below
|
|
57
58
|
|
|
58
|
-
import {BasicStrategy} from 'passport-http';
|
|
59
|
+
import {BasicStrategy} from 'passport-http';
|
|
59
60
|
|
|
60
|
-
function verify(username: string, password: string, cb: Function) {
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
const basicStrategy = new BasicStrategy(verify);
|
|
64
|
-
```
|
|
61
|
+
function verify(username: string, password: string, cb: Function) {
|
|
62
|
+
users.find(username, password, cb);
|
|
63
|
+
}
|
|
64
|
+
const basicStrategy = new BasicStrategy(verify);
|
|
65
|
+
```
|
|
65
66
|
|
|
66
|
-
It's a similar configuration as you add a strategy to a `passport` by calling
|
|
67
|
-
`passport.use()`.
|
|
67
|
+
It's a similar configuration as you add a strategy to a `passport` by calling
|
|
68
|
+
`passport.use()`.
|
|
68
69
|
|
|
69
70
|
2. Supply a _user profile factory_ which converts a user to a user profile. It
|
|
70
71
|
must abide by the `UserProfileFactory` interface supplied by
|
|
71
72
|
`@loopback/authentication@3.x`.
|
|
72
73
|
|
|
73
|
-
It is shown below for your convenience.
|
|
74
|
+
It is shown below for your convenience.
|
|
74
75
|
|
|
75
|
-
```ts
|
|
76
|
-
export interface UserProfileFactory<U> {
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
```
|
|
76
|
+
```ts
|
|
77
|
+
export interface UserProfileFactory<U> {
|
|
78
|
+
(user: U): UserProfile;
|
|
79
|
+
}
|
|
80
|
+
```
|
|
80
81
|
|
|
81
|
-
A default user profile factory is provided for you in the StrategyAdapter
|
|
82
|
-
constructor, but it does very little. It simply returns the user model as-is.
|
|
82
|
+
A default user profile factory is provided for you in the StrategyAdapter
|
|
83
|
+
constructor, but it does very little. It simply returns the user model as-is.
|
|
83
84
|
|
|
84
|
-
```ts
|
|
85
|
-
private userProfileFactory: UserProfileFactory<U> = (u: unknown) => {
|
|
86
|
-
|
|
87
|
-
},
|
|
88
|
-
```
|
|
85
|
+
```ts
|
|
86
|
+
private userProfileFactory: UserProfileFactory<U> = (u: unknown) => {
|
|
87
|
+
return u as UserProfile;
|
|
88
|
+
},
|
|
89
|
+
```
|
|
89
90
|
|
|
90
|
-
So it is recommended you provide a more meaningful mapping.
|
|
91
|
+
So it is recommended you provide a more meaningful mapping.
|
|
91
92
|
|
|
92
|
-
An example of a user profile factory converting a specific user type `MyUser`
|
|
93
|
-
type `UserProfile` is shown below.
|
|
93
|
+
An example of a user profile factory converting a specific user type `MyUser`
|
|
94
|
+
to type `UserProfile` is shown below.
|
|
94
95
|
|
|
95
|
-
```ts
|
|
96
|
-
//In file 'my.userprofile.factory.ts'
|
|
96
|
+
```ts
|
|
97
|
+
//In file 'my.userprofile.factory.ts'
|
|
97
98
|
|
|
98
|
-
import {UserProfileFactory} from '@loopback/authentication';
|
|
99
|
-
import {securityId, UserProfile} from '@loopback/security';
|
|
99
|
+
import {UserProfileFactory} from '@loopback/authentication';
|
|
100
|
+
import {securityId, UserProfile} from '@loopback/security';
|
|
100
101
|
|
|
101
|
-
export const myUserProfileFactory: UserProfileFactory<MyUser> = function (
|
|
102
|
-
|
|
103
|
-
): UserProfile {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
};
|
|
107
|
-
```
|
|
102
|
+
export const myUserProfileFactory: UserProfileFactory<MyUser> = function (
|
|
103
|
+
user: MyUser,
|
|
104
|
+
): UserProfile {
|
|
105
|
+
const userProfile = {[securityId]: user.id};
|
|
106
|
+
return userProfile;
|
|
107
|
+
};
|
|
108
|
+
```
|
|
108
109
|
|
|
109
110
|
3. Apply the adapter to the strategy
|
|
110
111
|
|
|
111
|
-
```ts
|
|
112
|
-
// In file 'my-basic-auth-strategy.ts'
|
|
113
|
-
import {BasicStrategy} from 'passport-http';
|
|
114
|
-
import {UserProfileFactory} from '@loopback/authentication';
|
|
115
|
-
import {securityId, UserProfile} from '@loopback/security';
|
|
116
|
-
import {myUserProfileFactory} from '<path to user profile factory>';
|
|
117
|
-
|
|
118
|
-
function verify(username: string, password: string, cb: Function) {
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
const basicStrategy = new BasicStrategy(verify);
|
|
122
|
-
|
|
123
|
-
// Apply the adapter
|
|
124
|
-
export const AUTH_STRATEGY_NAME = 'basic';
|
|
125
|
-
export const basicAuthStrategy = new StrategyAdapter(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
);
|
|
136
|
-
```
|
|
112
|
+
```ts
|
|
113
|
+
// In file 'my-basic-auth-strategy.ts'
|
|
114
|
+
import {BasicStrategy} from 'passport-http';
|
|
115
|
+
import {UserProfileFactory} from '@loopback/authentication';
|
|
116
|
+
import {securityId, UserProfile} from '@loopback/security';
|
|
117
|
+
import {myUserProfileFactory} from '<path to user profile factory>';
|
|
118
|
+
|
|
119
|
+
function verify(username: string, password: string, cb: Function) {
|
|
120
|
+
users.find(username, password, cb);
|
|
121
|
+
}
|
|
122
|
+
const basicStrategy = new BasicStrategy(verify);
|
|
123
|
+
|
|
124
|
+
// Apply the adapter
|
|
125
|
+
export const AUTH_STRATEGY_NAME = 'basic';
|
|
126
|
+
export const basicAuthStrategy = new StrategyAdapter(
|
|
127
|
+
// The configured basic strategy instance
|
|
128
|
+
basicStrategy,
|
|
129
|
+
// Give the strategy a name
|
|
130
|
+
// You'd better define your strategy name as a constant, like
|
|
131
|
+
// `const AUTH_STRATEGY_NAME = 'basic'`.
|
|
132
|
+
// You will need to decorate the APIs later with the same name.
|
|
133
|
+
AUTH_STRATEGY_NAME,
|
|
134
|
+
// Provide a user profile factory
|
|
135
|
+
myUserProfileFactory,
|
|
136
|
+
);
|
|
137
|
+
```
|
|
137
138
|
|
|
138
139
|
4. Register(bind) the strategy to app
|
|
139
140
|
|
|
140
|
-
```ts
|
|
141
|
-
import {Application, CoreTags} from '@loopback/core';
|
|
142
|
-
import {AuthenticationBindings} from '@loopback/authentication';
|
|
143
|
-
import {basicAuthStrategy} from './my-basic-auth-strategy';
|
|
144
|
-
|
|
145
|
-
app
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
```
|
|
141
|
+
```ts
|
|
142
|
+
import {Application, CoreTags} from '@loopback/core';
|
|
143
|
+
import {AuthenticationBindings} from '@loopback/authentication';
|
|
144
|
+
import {basicAuthStrategy} from './my-basic-auth-strategy';
|
|
145
|
+
|
|
146
|
+
app
|
|
147
|
+
.bind('authentication.strategies.basicAuthStrategy')
|
|
148
|
+
.to(basicAuthStrategy)
|
|
149
|
+
.tag({
|
|
150
|
+
[CoreTags.EXTENSION_FOR]:
|
|
151
|
+
AuthenticationBindings.AUTHENTICATION_STRATEGY_EXTENSION_POINT_NAME,
|
|
152
|
+
});
|
|
153
|
+
```
|
|
153
154
|
|
|
154
155
|
5. Decorate your endpoint
|
|
155
156
|
|
|
156
|
-
To authenticate your request with the basic strategy, decorate your
|
|
157
|
-
function like:
|
|
158
|
-
|
|
159
|
-
```ts
|
|
160
|
-
import {AUTH_STRATEGY_NAME} from './my-basic-auth-strategy';
|
|
161
|
-
import {SecurityBindings, UserProfile} from '@loopback/security';
|
|
162
|
-
import {authenticate} from '@loopback/authentication';
|
|
163
|
-
|
|
164
|
-
class MyController {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
```
|
|
157
|
+
To authenticate your request with the basic strategy, decorate your
|
|
158
|
+
controller function like:
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
import {AUTH_STRATEGY_NAME} from './my-basic-auth-strategy';
|
|
162
|
+
import {SecurityBindings, UserProfile} from '@loopback/security';
|
|
163
|
+
import {authenticate} from '@loopback/authentication';
|
|
164
|
+
|
|
165
|
+
class MyController {
|
|
166
|
+
constructor(
|
|
167
|
+
@inject(SecurityBindings.USER, {optional: true})
|
|
168
|
+
private user: UserProfile,
|
|
169
|
+
) {}
|
|
170
|
+
|
|
171
|
+
// Define your strategy name as a constant so that
|
|
172
|
+
// it is consistent with the name you provide in the adapter
|
|
173
|
+
@authenticate(AUTH_STRATEGY_NAME)
|
|
174
|
+
async whoAmI(): Promise<string> {
|
|
175
|
+
return this.user.id;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
```
|
|
178
179
|
|
|
179
180
|
6. Add the authentication action to your sequence
|
|
180
181
|
|
|
181
|
-
This part is same as registering a non-passport based strategy. Please make
|
|
182
|
-
you follow the documentation
|
|
183
|
-
[adding-an-authentication-action-to-a-custom-sequence](https://loopback.io/doc/en/lb4/Loopback-component-authentication.html#adding-an-authentication-action-to-a-custom-sequence)
|
|
184
|
-
to rewrite your sequence. You can also find a sample implementation in
|
|
185
|
-
[this example tutorial](https://loopback.io/doc/en/lb4/Authentication-tutorial.html#creating-a-custom-sequence-and-adding-the-authentication-action).
|
|
182
|
+
This part is same as registering a non-passport based strategy. Please make
|
|
183
|
+
sure you follow the documentation
|
|
184
|
+
[adding-an-authentication-action-to-a-custom-sequence](https://loopback.io/doc/en/lb4/Loopback-component-authentication.html#adding-an-authentication-action-to-a-custom-sequence)
|
|
185
|
+
to rewrite your sequence. You can also find a sample implementation in
|
|
186
|
+
[this example tutorial](https://loopback.io/doc/en/lb4/Authentication-tutorial.html#creating-a-custom-sequence-and-adding-the-authentication-action).
|
|
186
187
|
|
|
187
188
|
### With Provider
|
|
188
189
|
|
|
@@ -196,199 +197,206 @@ in
|
|
|
196
197
|
|
|
197
198
|
1. Create a provider for the strategy
|
|
198
199
|
|
|
199
|
-
Use `passport-http` as the example again:
|
|
200
|
-
|
|
201
|
-
```ts
|
|
202
|
-
// Create a file named `my-basic-auth-strategy.ts` to define your strategy below
|
|
203
|
-
|
|
204
|
-
import {AuthenticationStrategy} from '@loopback/authentication';
|
|
205
|
-
import {Provider} from '@loopback/core';
|
|
206
|
-
|
|
207
|
-
class PassportBasicAuthProvider implements Provider<AuthenticationStrategy> {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
}
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
The Provider should have two functions:
|
|
215
|
-
|
|
216
|
-
- A function that takes in the verify callback function and returns a
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
import {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
200
|
+
Use `passport-http` as the example again:
|
|
201
|
+
|
|
202
|
+
```ts
|
|
203
|
+
// Create a file named `my-basic-auth-strategy.ts` to define your strategy below
|
|
204
|
+
|
|
205
|
+
import {AuthenticationStrategy} from '@loopback/authentication';
|
|
206
|
+
import {Provider} from '@loopback/core';
|
|
207
|
+
|
|
208
|
+
class PassportBasicAuthProvider implements Provider<AuthenticationStrategy> {
|
|
209
|
+
value(): AuthenticationStrategy {
|
|
210
|
+
// The code that returns the converted strategy
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
The Provider should have two functions:
|
|
216
|
+
|
|
217
|
+
- A function that takes in the verify callback function and returns a
|
|
218
|
+
configured basic strategy. To know more about the configuration, please
|
|
219
|
+
check
|
|
220
|
+
[the configuration guide in module `passport-http`](https://github.com/jaredhanson/passport-http#usage-of-http-basic).
|
|
221
|
+
|
|
222
|
+
- A function that applies the `StrategyAdapter` to the configured basic
|
|
223
|
+
strategy instance. Then in the `value()` function, you return the converted
|
|
224
|
+
strategy.
|
|
225
|
+
|
|
226
|
+
So a full implementation of the provider is:
|
|
227
|
+
|
|
228
|
+
```ts
|
|
229
|
+
// In file 'providers/my-basic-auth-strategy.ts'
|
|
230
|
+
|
|
231
|
+
import {BasicStrategy, BasicVerifyFunction} from 'passport-http';
|
|
232
|
+
import {StrategyAdapter} from `@loopback/passport-adapter`;
|
|
233
|
+
import {
|
|
234
|
+
AuthenticationStrategy,
|
|
235
|
+
AuthenticationBindings,
|
|
236
|
+
} from '@loopback/authentication';
|
|
237
|
+
import {Provider, inject} from '@loopback/core';
|
|
238
|
+
|
|
239
|
+
export class PassportBasicAuthProvider<MyUser>
|
|
240
|
+
implements Provider<AuthenticationStrategy> {
|
|
241
|
+
constructor(
|
|
242
|
+
@inject('authentication.basic.verify')
|
|
243
|
+
private verifyFn: BasicVerifyFunction,
|
|
244
|
+
@inject(AuthenticationBindings.USER_PROFILE_FACTORY)
|
|
245
|
+
private myUserProfileFactory: UserProfileFactory<MyUser>,
|
|
246
|
+
) {}
|
|
247
|
+
|
|
248
|
+
value(): AuthenticationStrategy {
|
|
249
|
+
const basicStrategy = this.configuredBasicStrategy(this.verifyFn);
|
|
250
|
+
return this.convertToAuthStrategy(basicStrategy);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Takes in the verify callback function and returns a configured basic strategy.
|
|
254
|
+
configuredBasicStrategy(verifyFn: BasicVerifyFunction): BasicStrategy {
|
|
255
|
+
return new BasicStrategy(verifyFn);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Applies the `StrategyAdapter` to the configured basic strategy instance.
|
|
259
|
+
// You'd better define your strategy name as a constant, like
|
|
260
|
+
// `const AUTH_STRATEGY_NAME = 'basic'`
|
|
261
|
+
// You will need to decorate the APIs later with the same name
|
|
262
|
+
// Pass in the user profile factory
|
|
263
|
+
convertToAuthStrategy(basic: BasicStrategy): AuthenticationStrategy {
|
|
264
|
+
return new StrategyAdapter(
|
|
265
|
+
basic,
|
|
266
|
+
AUTH_STRATEGY_NAME,
|
|
267
|
+
this.myUserProfileFactory,
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
```
|
|
269
272
|
|
|
270
273
|
2. Create a provider for the verify function.
|
|
271
274
|
|
|
272
|
-
Here is an example provider named VerifyFunctionProvider which has a
|
|
273
|
-
method that returns a function of type BasicVerifyFunction.
|
|
274
|
-
|
|
275
|
-
```ts
|
|
276
|
-
// In file 'providers/verifyfn.provider.ts'
|
|
277
|
-
|
|
278
|
-
import {Provider} from '@loopback/core';
|
|
279
|
-
import {repository} from '@loopback/repository';
|
|
280
|
-
import {BasicVerifyFunction} from 'passport-http';
|
|
281
|
-
import {INVALID_USER_CREDENTIALS_MESSAGE} from '../keys';
|
|
282
|
-
|
|
283
|
-
export class VerifyFunctionProvider
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
275
|
+
Here is an example provider named VerifyFunctionProvider which has a
|
|
276
|
+
`value()` method that returns a function of type BasicVerifyFunction.
|
|
277
|
+
|
|
278
|
+
```ts
|
|
279
|
+
// In file 'providers/verifyfn.provider.ts'
|
|
280
|
+
|
|
281
|
+
import {Provider} from '@loopback/core';
|
|
282
|
+
import {repository} from '@loopback/repository';
|
|
283
|
+
import {BasicVerifyFunction} from 'passport-http';
|
|
284
|
+
import {INVALID_USER_CREDENTIALS_MESSAGE} from '../keys';
|
|
285
|
+
|
|
286
|
+
export class VerifyFunctionProvider
|
|
287
|
+
implements Provider<BasicVerifyFunction> {
|
|
288
|
+
constructor(@repository('users') private userRepo: MyUserRepository) {}
|
|
289
|
+
|
|
290
|
+
value(): BasicVerifyFunction {
|
|
291
|
+
const myThis = this;
|
|
292
|
+
|
|
293
|
+
return async function (
|
|
294
|
+
username: string,
|
|
295
|
+
password: string,
|
|
296
|
+
cb: Function,
|
|
297
|
+
) {
|
|
298
|
+
let user: MyUser;
|
|
299
|
+
|
|
300
|
+
try {
|
|
301
|
+
//find user with specific username
|
|
302
|
+
const users: MyUser[] = await myThis.userRepo.find({
|
|
303
|
+
where: {username: username},
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
// if no user found with this username, throw an error.
|
|
307
|
+
if (users.length < 1) {
|
|
308
|
+
let error = new Error(INVALID_USER_CREDENTIALS_MESSAGE); //assign 401 in sequence
|
|
309
|
+
throw error;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
//verify given password matches the user's password
|
|
313
|
+
user = users[0];
|
|
314
|
+
if (user.password !== password) {
|
|
315
|
+
let error = new Error(INVALID_USER_CREDENTIALS_MESSAGE); //assign 401 in sequence
|
|
316
|
+
throw error;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
//return null for error, and the valid user
|
|
320
|
+
cb(null, user);
|
|
321
|
+
} catch (error) {
|
|
322
|
+
//return the error, and null for the user
|
|
323
|
+
cb(error, null);
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
```
|
|
321
329
|
|
|
322
330
|
3. Register(bind) the providers
|
|
323
331
|
|
|
324
|
-
Register **VerifyFunctionProvider** which is required by
|
|
325
|
-
**PassportBasicAuthProvider**. Then register **PassportBasicAuthProvider** in
|
|
326
|
-
your LoopBack application so that the authentication system can look for your
|
|
327
|
-
strategy by name and invoke it.
|
|
328
|
-
|
|
329
|
-
```ts
|
|
330
|
-
// In the main file
|
|
331
|
-
|
|
332
|
-
import {addExtension} from '@loopback/core';
|
|
333
|
-
import {MyApplication} from '<path_to_your_app>';
|
|
334
|
-
import {PassportBasicAuthProvider} from '<path_to_the_provider>';
|
|
335
|
-
import {VerifyFunctionProvider} from '<path_to_the_provider>';
|
|
336
|
-
import {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
} from '@loopback/authentication';
|
|
340
|
-
|
|
341
|
-
const app = new MyApplication();
|
|
342
|
-
|
|
343
|
-
//load the authentication component
|
|
344
|
-
app.component(AuthenticationComponent);
|
|
345
|
-
|
|
346
|
-
// bind the user repo
|
|
347
|
-
app.bind('repositories.users').toClass(MyUserRepository);
|
|
348
|
-
|
|
349
|
-
// bind the authenticated sequence (mentioned later in this document)
|
|
350
|
-
app.sequence(MyAuthenticationSequence);
|
|
351
|
-
|
|
352
|
-
// the verify function for passport-http
|
|
353
|
-
app.bind('authentication.basic.verify').toProvider(VerifyFunctionProvider);
|
|
354
|
-
|
|
355
|
-
// register PassportBasicAuthProvider as a custom authentication strategy
|
|
356
|
-
addExtension(
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
);
|
|
365
|
-
```
|
|
332
|
+
Register **VerifyFunctionProvider** which is required by
|
|
333
|
+
**PassportBasicAuthProvider**. Then register **PassportBasicAuthProvider** in
|
|
334
|
+
your LoopBack application so that the authentication system can look for your
|
|
335
|
+
strategy by name and invoke it.
|
|
336
|
+
|
|
337
|
+
```ts
|
|
338
|
+
// In the main file
|
|
339
|
+
|
|
340
|
+
import {addExtension} from '@loopback/core';
|
|
341
|
+
import {MyApplication} from '<path_to_your_app>';
|
|
342
|
+
import {PassportBasicAuthProvider} from '<path_to_the_provider>';
|
|
343
|
+
import {VerifyFunctionProvider} from '<path_to_the_provider>';
|
|
344
|
+
import {
|
|
345
|
+
AuthenticationBindings,
|
|
346
|
+
AuthenticationComponent,
|
|
347
|
+
} from '@loopback/authentication';
|
|
348
|
+
|
|
349
|
+
const app = new MyApplication();
|
|
350
|
+
|
|
351
|
+
//load the authentication component
|
|
352
|
+
app.component(AuthenticationComponent);
|
|
353
|
+
|
|
354
|
+
// bind the user repo
|
|
355
|
+
app.bind('repositories.users').toClass(MyUserRepository);
|
|
356
|
+
|
|
357
|
+
// bind the authenticated sequence (mentioned later in this document)
|
|
358
|
+
app.sequence(MyAuthenticationSequence);
|
|
359
|
+
|
|
360
|
+
// the verify function for passport-http
|
|
361
|
+
app.bind('authentication.basic.verify').toProvider(VerifyFunctionProvider);
|
|
362
|
+
|
|
363
|
+
// register PassportBasicAuthProvider as a custom authentication strategy
|
|
364
|
+
addExtension(
|
|
365
|
+
app,
|
|
366
|
+
AuthenticationBindings.AUTHENTICATION_STRATEGY_EXTENSION_POINT_NAME,
|
|
367
|
+
PassportBasicAuthProvider,
|
|
368
|
+
{
|
|
369
|
+
namespace:
|
|
370
|
+
AuthenticationBindings.AUTHENTICATION_STRATEGY_EXTENSION_POINT_NAME,
|
|
371
|
+
},
|
|
372
|
+
);
|
|
373
|
+
```
|
|
366
374
|
|
|
367
375
|
4. Decorate your endpoint
|
|
368
376
|
|
|
369
|
-
To authenticate your request with the basic strategy, decorate your
|
|
370
|
-
function like:
|
|
377
|
+
To authenticate your request with the basic strategy, decorate your
|
|
378
|
+
controller function like:
|
|
371
379
|
|
|
372
|
-
```ts
|
|
373
|
-
import {AUTH_STRATEGY_NAME} from './my-basic-auth-strategy';
|
|
374
|
-
import {authenticate} from '@loopback/authentication';
|
|
380
|
+
```ts
|
|
381
|
+
import {AUTH_STRATEGY_NAME} from './my-basic-auth-strategy';
|
|
382
|
+
import {authenticate} from '@loopback/authentication';
|
|
375
383
|
|
|
376
|
-
class MyController {
|
|
377
|
-
|
|
384
|
+
class MyController {
|
|
385
|
+
constructor(@inject(SecurityBindings.USER) private user: UserProfile) {}
|
|
378
386
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
}
|
|
386
|
-
```
|
|
387
|
+
// Define your strategy name as a constant so that
|
|
388
|
+
// it is consistent with the name you provide in the adapter
|
|
389
|
+
@authenticate(AUTH_STRATEGY_NAME)
|
|
390
|
+
async whoAmI(): Promise<string> {
|
|
391
|
+
return this.user.id;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
```
|
|
387
395
|
|
|
388
396
|
5. Add the authentication action to your sequence
|
|
389
397
|
|
|
390
|
-
This part is same as registering a non-passport based strategy. Please make
|
|
391
|
-
you follow the documentation
|
|
392
|
-
[adding-an-authentication-action-to-a-custom-sequence](https://loopback.io/doc/en/lb4/Loopback-component-authentication.html#adding-an-authentication-action-to-a-custom-sequence)
|
|
393
|
-
to rewrite your sequence. You can also find a sample implementation in
|
|
394
|
-
[this example tutorial](https://loopback.io/doc/en/lb4/Authentication-tutorial.html#creating-a-custom-sequence-and-adding-the-authentication-action).
|
|
398
|
+
This part is same as registering a non-passport based strategy. Please make
|
|
399
|
+
sure you follow the documentation
|
|
400
|
+
[adding-an-authentication-action-to-a-custom-sequence](https://loopback.io/doc/en/lb4/Loopback-component-authentication.html#adding-an-authentication-action-to-a-custom-sequence)
|
|
401
|
+
to rewrite your sequence. You can also find a sample implementation in
|
|
402
|
+
[this example tutorial](https://loopback.io/doc/en/lb4/Authentication-tutorial.html#creating-a-custom-sequence-and-adding-the-authentication-action).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loopback/authentication-passport",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.13",
|
|
4
4
|
"description": "A package creating adapters between the passport module and @loopback/authentication",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -40,38 +40,37 @@
|
|
|
40
40
|
"directory": "extensions/authentication-passport"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@loopback/authentication": "^
|
|
44
|
-
"@loopback/core": "^2.9.
|
|
45
|
-
"@loopback/
|
|
46
|
-
"@loopback/
|
|
47
|
-
"@loopback/security": "^0.2.14",
|
|
43
|
+
"@loopback/authentication": "^6.0.1",
|
|
44
|
+
"@loopback/core": "^2.9.5",
|
|
45
|
+
"@loopback/rest": "^6.2.0",
|
|
46
|
+
"@loopback/security": "^0.2.18",
|
|
48
47
|
"passport": "^0.4.1",
|
|
49
|
-
"tslib": "^2.0.
|
|
48
|
+
"tslib": "^2.0.1",
|
|
50
49
|
"util-promisifyall": "^1.0.6"
|
|
51
50
|
},
|
|
52
51
|
"devDependencies": {
|
|
53
|
-
"@loopback/build": "^6.
|
|
54
|
-
"@loopback/eslint-config": "^
|
|
55
|
-
"@loopback/mock-oauth2-provider": "^0.1.
|
|
56
|
-
"@loopback/openapi-spec-builder": "^2.1.
|
|
57
|
-
"@loopback/testlab": "^3.2.
|
|
52
|
+
"@loopback/build": "^6.2.2",
|
|
53
|
+
"@loopback/eslint-config": "^9.0.2",
|
|
54
|
+
"@loopback/mock-oauth2-provider": "^0.1.7",
|
|
55
|
+
"@loopback/openapi-spec-builder": "^2.1.13",
|
|
56
|
+
"@loopback/testlab": "^3.2.4",
|
|
58
57
|
"@types/jsonwebtoken": "^8.5.0",
|
|
59
|
-
"@types/lodash": "^4.14.
|
|
60
|
-
"@types/node": "^10.17.
|
|
61
|
-
"@types/passport": "^1.0.
|
|
58
|
+
"@types/lodash": "^4.14.160",
|
|
59
|
+
"@types/node": "^10.17.28",
|
|
60
|
+
"@types/passport": "^1.0.4",
|
|
62
61
|
"@types/passport-http": "^0.3.8",
|
|
63
62
|
"@types/passport-oauth2": "^1.4.9",
|
|
64
|
-
"@types/qs": "^6.9.
|
|
65
|
-
"axios": "^0.
|
|
63
|
+
"@types/qs": "^6.9.4",
|
|
64
|
+
"axios": "^0.20.0",
|
|
66
65
|
"body-parser": "^1.19.0",
|
|
67
66
|
"express": "^4.17.1",
|
|
68
67
|
"form-data": "^3.0.0",
|
|
69
68
|
"jsonwebtoken": "^8.5.1",
|
|
70
|
-
"lodash": "^4.17.
|
|
69
|
+
"lodash": "^4.17.20",
|
|
71
70
|
"passport-http": "^0.3.0",
|
|
72
71
|
"passport-oauth2": "^1.5.0",
|
|
73
72
|
"qs": "^6.9.4",
|
|
74
73
|
"supertest": "^4.0.2"
|
|
75
74
|
},
|
|
76
|
-
"gitHead": "
|
|
75
|
+
"gitHead": "a3f54273814de63819e0d8bc86509f8a737800bb"
|
|
77
76
|
}
|