@hgmap/lbext-auth v2.0.2
@hgmap/lbext-auth
A Loopback 4 authentication out of the box. Include DataSources,Models,Repositories artifacts.
Overview
This component contains datasources,models,repositories for speed up your start with an authentication of Loopback 4 application.
Fast Start
lb4 app-test
cd app-test/ && npm install --save @hgmap/lbext-auth
cp node_modules/\@hgmap/lbext-auth/examples/application.ts src/
cp node_modules/\@hgmap/lbext-auth/examples/sequence.ts src/
cp node_modules/\@hgmap/lbext-auth/examples/defaultUsers.json ./
this database contains all users with password '12345678' (e.g. { login: 'mpavlov02@email.me', password: '12345678' })npm run start
Application class name is AppTestApplication by default. You can rename it.
Usage:
npm install --save @hgmap/lbext-auth
Edit
application.ts
by adding import from this component and activate it by callingapp.component()
method of the application and add component (@hgmap/lbext-auth) configuration.
You can use default artifacts (controllers,models,datasources,repositories) if you don't need any specific features.
...
options.lbextAuth = {
defaultArtifacts: {
repositories: {
repoUser: true // use UserRepository from component; if false then use copy or your own from <projDir>/src/repositories/<UserRepository>.ts
},
controllers: {
auth: true, // use AuthController from component; if false then use copy or your own from <projDir>/src/controllers/<AuthController>.ts
user: true, // use UserController from component; if false then use copy or your own from <projDir>/src/controllers/<UserController>.ts
},
datasources: {
dataUser: true, // use UserDataSource from component; if false then use copy or your own from <projDir>/src/datasources/<UserDataSource>.ts
// if it's true, you can also reconfigure datasource by it's config only in the UserServiceBindings.DS_CFG variable
},
},
};
...
Also you can copy needed files to your project source directory from component sources node_modules/@hgmap/lbext-auth/src/default-artifacts/<needed part>
You may want to following some scenarios:
- overwrite config of default datasource (use another connector or destination path of memory data file)
- create your own (or copy default ones to application source directory) datasource(s) and set
defaultArtifacts.datasources.dataUser = false
- create your own (or copy default ones to application source directory) repositories and set
defaultArtifacts.repositories.repoUser = false
and create your own (or copy default ones to application source directory) model(s) and it's relations - create your own (or copy default ones to application source directory) controller(s) and set
defaultArtifacts.controllers.<auth or/and user> = false
- Edit
sequence.ts
by adding import from this component and insert one line of code that calling of.AUTH_ACTION
from AuthenticationBindings imported.
User database is in the process.cwd()+'/defaultUsers.json'
by default. But you can change it by configure (see #1
)
That's all
All you need is @authenticate('jwt')
on every method to be authenticated !
src/sequence.ts
...
++ import {
++ AuthenticateFn,
++ AuthenticationBindings,
++ } from '@hgmap/lbext-auth';
...
export class MySequence implements SequenceHandler {
constructor(
...
++ @inject(AuthenticationBindings.AUTH_ACTION) public authRequest: AuthenticateFn,
) {}
async handle(context: RequestContext) {
try {
const {request, response} = context;
const route = this.findRoute(request);
++ await this.authRequest(request);
const args = await this.parseParams(request, route);
const result = await this.invoke(route, args);
this.send(response, result);
} catch (err) {
this.reject(context, err);
}
}
}
src/application.ts
...
++ import {
++ AuthComponent, TokenServiceBindings, PasswordServiceBindings, UserServiceBindings,
++ } from '@hgmap/lbext-auth';
export class ApiCoreApplication extends BootMixin(
ServiceMixin(RepositoryMixin(RestApplication)),
) {
constructor(options: ApplicationConfig = {}) {
super(options);
...
// component lbext-auth config
++ options.lbextAuth = {
++ defaultArtifacts: {
++ repositories: {
++ repoUser: true // use UserRepository from component; if false then use copy or your own from <projDir>/src/repositories/<UserRepository>.ts
++ },
++ controllers: {
++ auth: true, // use AuthController from component; if false then use copy or your own from <projDir>/src/controllers/<AuthController>.ts
++ user: true, // use UserController from component; if false then use copy or your own from <projDir>/src/controllers/<UserController>.ts
++ },
++ datasources: {
++ dataUser: true, // use UserDataSource from component; if false then use copy or your own from <projDir>/src/datasources/<UserDataSource>.ts
// if it's true, you can also reconfigure datasource by it's config only in the UserServiceBindings.DS_CFG variable
++ },
++ },
++ };
++ this.component(AuthComponent);
/**
configure TokenService (for JWT authentication) and PasswordService (hash settings)
*/
// default: "ZDUwYTc3OGM4Y2NjOTUwODQ0NTMyNWU3MWJlZmJjOTI3ZWUwNzRmMSAgLQo="
++ this.bind(TokenServiceBindings.SECRET).to('AS SECRET YOU CAN USE RS256 ALG WITH CERTIFICATE');
/**
you can create and use certificate:
const private_key = fs.readFileSync('path/to/cert/directory/private.key','utf8'); - for generateToken - as your secret
const public_key = fs.readFileSync('path/to/cert/directory/public.key','utf8'); - for verifyToken - you can use it on many other servers...
*/
// default: "LoopbackApp"
++ this.bind(TokenServiceBindings.ISSUER).to('Issuer');
// default: "Loopback"
++ this.bind(TokenServiceBindings.AUDIENCE).to('Audience');
// default: "600" NOTE: string
++ this.bind(TokenServiceBindings.EXPIRES_IN).to('600');
// default: "MzQ5MjBhZGQyYTZhZmJkNzJiZmNlNDc0NGU0OWVhMTg1NDk0YzM4YiAgLQo="
++ this.bind(PasswordServiceBindings.SALT).to('SALT ITS NOT REQUIRED');
// default: 64 bytes - hash length
++ this.bind(PasswordServiceBindings.LENGTH).to('64');
/**
if defaultArtifacts.datasources.dataUser is true (also any of available datasources) then you can reconfigure default UserDataSource (overwrite config)
by binding of datasource config to UserServiceBindings.DS_CFG. See below
---
this.bind(UserServiceBindings.DS_CFG).to({
"name": "dbusers",
"connector": "memory",
"localStorage": "",
"file": process.cwd()+'/db-users.json',
});
---
or use your favourite connector...
if you didn't define datasource User that use the default one from component
then you need uncomment lines below and copy defaults/create your own datasource.
As below:
---
this.bind(UserServiceBindings.DS).toClass(UserDataSource);
---
if you didn't define defaultArtifacts.repositories or set defaultArtifacts.repositories.repoUser to false
then you need copy default to your application src/repositories directory or create your own by lb4/manual
And bind it to UserServiceBindings.REPO_USER as you can see below:
---
this.bind(UserServiceBindings.REPO_USER).toClass(UserRepository);
---
NOTE: you also need to create User model and UserRelations ...
*/
}
}
Default login in API explorer (swagger)
Swagger user interface of API explorer is on localhost:3000/explorer
by default
To be logged in you need go through some steps:
- Create the first user in the top application directory (the same level of
src/
anddist/
directories) in the filedefaultUsers.json
or in your database if you use your own...
{
"ids": {
"User": 2
},
"models": {
"User": {
"1": "{\"id\":1,\"firstname\":\"John\",\"lastname\":\"Travolta\",\"username\":\"JT100\",\"email\":\"whatever@email.me\",\"password\":\"rDFsmb5END6nX7denegFLEed7UA3YwEBGQvqNjrdnT9Jk1OrsCAGVM4kh16xt5DCrsxxpT4YF6t3tNSl7hcFSQ==\"}"
}
}
}
copy and paste above code to this file. Credentials of this new user is login: whatever@email.me and password: 12345678
.
go to
localhost:3000
and press on theAuthorize
buttonenter login and password to basic authentication part.
press on to
/login/basic
method, then press on totry it out
and pressexecute
. Alternatively, you can insert credentials to request body data of the/login/json
method... This actions returns token that needed to authenticate for all other methods.
- press method
- press
try it out
- press
execute
- got token
- This token need to be pasted to Authorization modal form - JWT part. (press
Authorize
button on the top of the page)
Now, You can do all of actions following 10 minutes (600 sec by default). Enjoy )