Skip to content

Commit 3423f6e

Browse files
committed
fix(authentication): update broken code in Readme
1 parent 20a41ac commit 3423f6e

File tree

1 file changed

+68
-52
lines changed

1 file changed

+68
-52
lines changed

packages/authentication/README.md

Lines changed: 68 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# @loopback/authentication
22

3-
A LoopBack component for authentication support.
3+
A LoopBack 4 component for authentication support.
44

55
**This is a reference implementation showing how to implement an authentication component, it is not production ready.**
66

77
## Overview
88

99
The component demonstrates how to leverage Passport module and extension points
10-
provided by LoopBack Next to implement an authentication layer.
10+
provided by LoopBack 4 to implement an authentication layer.
1111

1212
## Installation
1313

@@ -20,18 +20,27 @@ npm install --save @loopback/authentication
2020
Start by decorating your controller methods with `@authenticate` to require
2121
the request to be authenticated.
2222

23+
In this example, we make the user profile available via dependency injection
24+
using a key available from `@loopback/authentication` package.
25+
2326
```ts
24-
// controllers/my-controller.ts
25-
import {UserProfile, authenticate, AuthenticationBindings} from '@loopback/authentication';
26-
import {inject} from '@loopback/core';
27+
// src/controllers/who-am-i.controller.ts
28+
import {inject} from '@loopback/context';
29+
import {
30+
AuthenticationBindings,
31+
UserProfile,
32+
authenticate,
33+
} from '@loopback/authentication';
2734
import {get} from '@loopback/rest';
2835

29-
export class MyController {
30-
constructor(@inject(AuthenticationBindings.CURRENT_USER) private user: UserProfile) {}
36+
export class WhoAmIController {
37+
constructor(
38+
@inject(AuthenticationBindings.CURRENT_USER) private user: UserProfile,
39+
) {}
3140

3241
@authenticate('BasicStrategy')
33-
@get('/whoAmI')
34-
whoAmI() {
42+
@get('/whoami')
43+
whoAmI(): string {
3544
return this.user.id;
3645
}
3746
}
@@ -42,19 +51,20 @@ in `@authenticate` decorators into Passport Strategy instances.
4251
Remember to install `passport`, `passport-http`, `@types/passport`, and
4352
`@types/passport-http` modules beforehand.
4453

54+
```shell
55+
npm install --save passport passport-http
56+
npm install --save-dev @types/passport @types/passport-http
57+
```
58+
4559
```ts
46-
// providers/auth-strategy.ts
47-
import {
48-
inject,
49-
Provider,
50-
ValueOrPromise,
51-
} from '@loopback/context';
60+
// src/providers/auth-strategy.provider.ts
61+
import {Provider, inject, ValueOrPromise} from '@loopback/context';
62+
import {Strategy} from 'passport';
5263
import {
5364
AuthenticationBindings,
5465
AuthenticationMetadata,
66+
UserProfile,
5567
} from '@loopback/authentication';
56-
57-
import {Strategy} from 'passport';
5868
import {BasicStrategy} from 'passport-http';
5969

6070
export class MyAuthStrategyProvider implements Provider<Strategy | undefined> {
@@ -63,8 +73,7 @@ export class MyAuthStrategyProvider implements Provider<Strategy | undefined> {
6373
private metadata: AuthenticationMetadata,
6474
) {}
6575

66-
value() : ValueOrPromise<Strategy | undefined> {
67-
76+
value(): ValueOrPromise<Strategy | undefined> {
6877
// The function was not decorated, so we shouldn't attempt authentication
6978
if (!this.metadata) {
7079
return undefined;
@@ -78,10 +87,14 @@ export class MyAuthStrategyProvider implements Provider<Strategy | undefined> {
7887
}
7988
}
8089

81-
verify(username: string, password: string, cb: Function) {
90+
verify(
91+
username: string,
92+
password: string,
93+
cb: (err: Error | null, user?: UserProfile | false) => void,
94+
) {
8295
// find user by name & password
8396
// call cb(null, false) when user not found
84-
// call cb(null, userProfile) when user is authenticated
97+
// call cb(null, user) when user is authenticated
8598
}
8699
}
87100
```
@@ -90,27 +103,20 @@ In order to perform authentication, we need to implement a custom Sequence
90103
invoking the authentication at the right time during the request handling.
91104

92105
```ts
93-
// sequence.ts
94-
import {
95-
inject,
96-
} from '@loopback/core';
97-
106+
// src/sequence.ts
98107
import {
108+
RestBindings,
109+
SequenceHandler,
99110
FindRoute,
100-
InvokeMethod,
101-
ParsedRequest,
102111
ParseParams,
103-
Reject,
112+
InvokeMethod,
104113
Send,
105-
ServerResponse,
106-
SequenceHandler,
107-
RestBindings,
114+
Reject,
115+
ParsedRequest,
108116
} from '@loopback/rest';
109-
110-
import {
111-
AuthenticateFn,
112-
AuthenticationBindings,
113-
} from '@loopback/authentication';
117+
import {inject} from '@loopback/context';
118+
import {AuthenticationBindings, AuthenticateFn} from '@loopback/authentication';
119+
import {ServerResponse} from 'http';
114120

115121
const SequenceActions = RestBindings.SequenceActions;
116122

@@ -145,45 +151,55 @@ export class MySequence implements SequenceHandler {
145151
Finally, put it all together in your application class:
146152

147153
```ts
154+
// src/application.ts
155+
import {BootMixin, Binding, Booter} from '@loopback/boot';
156+
import {RestApplication, RestServer} from '@loopback/rest';
148157
import {
149158
AuthenticationComponent,
150159
AuthenticationBindings,
151160
} from '@loopback/authentication';
152-
import {RestApplication, RestServer} from '@loopback/rest';
153-
import {MyAuthStrategyProvider} from './providers/auth-strategy';
154-
import {MyController} from './controllers/my-controller';
161+
import {MyAuthStrategyProvider} from './providers/auth-strategy.provider';
155162
import {MySequence} from './sequence';
163+
import {ApplicationConfig} from '@loopback/core';
164+
165+
export class MyApp extends BootMixin(RestApplication) {
166+
constructor(options?: ApplicationConfig) {
167+
super(options);
156168

157-
class MyApp extends RestApplication {
158-
constructor() {
159-
super();
169+
this.projectRoot = __dirname;
160170

161171
this.component(AuthenticationComponent);
162-
this
163-
.bind(AuthenticationBindings.STRATEGY)
164-
.toProvider(MyAuthStrategyProvider);
172+
this.bind(AuthenticationBindings.STRATEGY).toProvider(
173+
MyAuthStrategyProvider,
174+
);
165175

166176
this.sequence(MySequence);
167-
168-
this.controller(MyController);
169177
}
170178

171179
async start() {
172180
await super.start();
173181

174182
const server = await this.getServer(RestServer);
175-
console.log(`REST server running on port: ${server.getSync('rest.port')}`);
183+
const port = await server.get('rest.port');
184+
console.log(`REST server running on port: ${port}`);
176185
}
177186
}
178187
```
179188

180189
You can try your authentication component by using your favourite REST client
181190
and by setting the `authorization` header. Here is an example of what your
182191
request might look like using curl:
192+
193+
```shell
194+
curl -u username:password http://localhost:3000/whoami
183195
```
196+
197+
or if you'd like to manually set the headers:
198+
199+
```shell
184200
curl -X GET \
185-
http://localhost:3000/whoami \
186-
-H 'authorization: Basic Zm9vOmJhcg=='
201+
http:/localhost:3000/whoami \
202+
-H 'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ='
187203
```
188204

189205
## Related resources
@@ -192,7 +208,7 @@ For more info about passport, see [passport.js](http://passportjs.org/).
192208

193209
## Contributions
194210

195-
- [Guidelines](https://github.com/strongloop/loopback-next/wiki/Contributing#guidelines)
211+
- [Guidelines](https://github.com/strongloop/loopback-next/blob/master/docs/site/DEVELOPING.md)
196212
- [Join the team](https://github.com/strongloop/loopback-next/issues/110)
197213

198214
## Tests

0 commit comments

Comments
 (0)