Skip to content

CodeCoupler API Auth Setup

  1. Create a MySql/MariaDB Database with the provided cc-api-auth.sql script in this package.
  2. Add a datasource with lb4 datasource and the name auth pointing to the newly created database.

Alternative 1: Create a complete new Loopback project

You can create a complete new project with all configurations ready with:

1
npm init cc-api

This will setup a boilerplate with some modifications and include @codecoupler/cc-api-auth.

Alternative 2: Integrate into an existing Loopback project

Add these packages to your Loopback project:

1
2
npm i @codecoupler/cc-api-auth
npm i dotenv

Add this to your application.ts (the place seems to be not too much relevant, but it is recommended to add these lines after the line with this.component(RestExplorerComponent);):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
//Authentication
//--------------

//Add Loopback's Authentication Component
this.component(AuthenticationComponent);
//Use this if you want to lock all rest endpoints with authentication by
//default. Do not forget to exclude the login controller in "sequence.ts".
//this.configure(AuthenticationBindings.COMPONENT).to({
//  defaultMetadata: {strategy: 'jwt'},
//});

//Add Auth Component of cc-api-auth
this.component(CcApiAuthComponent);

//Define the DataSource which is needed for Authentication and Authorization
this.bind(CcApiAuthComponentBindings.DATA_SOURCE).to(new AuthDataSource());

//Specify the options for the JWT Authentication Strategy. Here we use the
//process environment, so we can set these options different for each
//system. These options can be overridden in each single @authenticate
//decorator.
this.bind(
  CcApiAuthComponentBindings.AUTHENTICATION_STRATEGIES_JWT_OPTIONS,
).to({
  secret: process.env.JWT_SECRET ?? '',
  issuer: process.env.JWT_ISSUER ?? '',
  expiredSeconds: process.env.JWT_EXP_SEC
    ? parseInt(process.env.JWT_EXP_SEC)
    : 0,
  cookieName: process.env.JWT_COOKIE_NAME ?? '',
});

// *******************************************************
// Optional add here login hook for external authorization
// Read below for further detail
// *******************************************************

//Register the provided JWT authentication strategy of cc-api-auth
registerAuthenticationStrategy(
  this,
  this.getSync<Constructor<AuthenticationStrategy>>(
    CcApiAuthComponentBindings.AUTHENTICATION_STRATEGIES_JWT_CLASS,
  ),
);

//Authorization
//-------------

//Add Loopback's Authorization Component
const authorizationOptions: AuthorizationOptions = {
  precedence: AuthorizationDecision.DENY,
  defaultDecision: AuthorizationDecision.DENY,
};
this.configure(AuthorizationBindings.COMPONENT).to(authorizationOptions);
this.component(AuthorizationComponent);

//Register the provided authorization provider of cc-api-auth
this.bind('authorizationProviders.cc-api-auth')
  .toProvider(
    this.getSync<Constructor<CcApiAuthorizationProvider>>(
      CcApiAuthComponentBindings.AUTHORIZATION_PROVIDER,
    ),
  )
  .tag(AuthorizationTags.AUTHORIZER);

Add this to your sequence.ts before this.invoke(...):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
//Add the authentication check
try {
  // If you have enabled the default authentication for
  // all controllers by default, you should exclude here
  // the login controller. Otherwise you cannot login:
  // if (!request.path.endsWith('/auth/login'))
  await this.authenticateRequest(request);
} catch (error) {
  if (error.code === AUTHENTICATION_STRATEGY_NOT_FOUND || error.code === USER_PROFILE_NOT_FOUND) {
    Object.assign(error, { statusCode: 401 /* Unauthorized */ });
  }
  this.reject(context, error);
  return;
}

Add this to your index.ts after await app.start() to ensure at least one administrator account (Please read the notes below for the function AddUserRolePermission):

1
await AddUserRolePermission(app, "admin", "admin", "admin", "admin.user");

Create an .env file in your project root folder:

1
2
3
4
JWT_SECRET=changeme
JWT_ISSUER=cc-api
JWT_EXP_SEC=300
JWT_COOKIE_NAME=JWT
  • JWT_SECRET: The secret key to encode/decode the JSON Web Token
  • JWT_ISSUER: The issuer of the JSON Web Token (can be any string you want)
  • JWT_EXP_SEC: The expiration time of the JSON Web Token
  • JWT_COOKIE_NAME: The cookie name where the JSON Web Token will be saved