#loopback-example-access-control
$ git clone https://github.com/strongloop/loopback-example-access-control
$ cd loopback-example-access-control
$ npm install
$ node .
In this example, we create "Startkicker" (a basic Kickstarter-like application) to demonstrate authentication and authorization mechanisms in LoopBack. The application consists of four types of users:
guestownerteam memberadministrator
Each user type has permission to perform tasks based on their role and the application's ACL (access control list) entries.
##Prerequisites
###Tutorials
- Getting started with LoopBack
- Tutorial series - step 1
- Tutorial series - step 2
- Tutorial series - step 3
###Knowledge
##Procedure
###Create the application
####Application information
- Name:
loopback-example-access-control - Directory to contain the project:
loopback-example-access-control
$ slc loopback loopback-example-access-control
... # follow the prompts
$ cd loopback-example-access-control
###Add the models
####Model information
- Name:
user- Datasource:
db (memory) - Base class:
User - Expose via REST:
No - Custom plural form: Leave blank
- Properties
- None
- Datasource:
- Name:
team- Datasource:
db (memory) - Base class:
PersistedModel - Expose via REST:
No - Custom plural form: Leave blank
- Properties
ownerId- Number
- Not required
memberId- Number
- Required
- Datasource:
- Name:
project- Datasource:
db (memory) - Base class:
PersistedModel - Expose via REST:
Yes - Custom plural form: Leave blank
- Properties
name- String
- Not required
balance- Number
- Not required
- Datasource:
No properties are required for the
usermodel because we inherit them from the built-inUsermodel by specifying it as the base class.
$ slc loopback:model user
... # follow the prompts, repeat for `team` and `project`
###Define the remote methods
Define three remote methods in project.js:
###Create the model relations
####Model relation information
user- has many
project- Property name for the relation:
projects - Custom foreign key:
ownerId - Require a through model: No
- Property name for the relation:
team- Property name for the relation:
teams - Custom foreign key:
ownerId - Require a through model: No
- Property name for the relation:
- has many
team- has many
user- Property name for the relation:
members - Custom foreign key:
memberId - Require a through model: No
- Property name for the relation:
- has many
project- belongs to
user- Property name for the relation:
user - Custom foreign key:
ownerId
- Property name for the relation:
- belongs to
###Add model instances
Create a boot script named sample-models.js.
This script does the following:
- Creates 3 users (
John,Jane, andBob) - Creates project 1, sets
Johnas the owner, and addsJohnandJaneas team members - Creates project 2, sets
Janeas the owner and solo team member - Creates a role named
adminand adds a role mapping to makeBobanadmin
###Configure server-side views
LoopBack comes preconfigured with EJS out-of-box. This means we can use server-side templating by simply setting the proper view engine and a directory to store the views.
Create a views directory to store server-side templates.
$ mkdir server/views
Add server-side templating configurations to server.js.
Create index.ejs in the views directory.
Configure server.js to use server-side
templating. Remember to import the path package.
###Add routes
Create routes.js. This script does the following:
- Sets the
GET /route to renderindex.ejs - Sets the
GET /projectsroute to renderprojects.ejs - Sets the
POST /projectsroute to to renderprojects.ejswhen credentials are valid and rendersindex.ejswhen credentials are invalid - Sets the
GET /logoutroute to log the user out
When you log in sucessfully,
projects.htmlis rendered with the authenticated user's access token embedded into each link.
###Create the views
Create the views directory to store views.
In this directory, create index.ejs and projects.ejs.
###Create a role resolver
Create role-resolver.js.
This file checks if the context relates to the project model and if the request maps to a user. If these two requirements are not met, the request is denied. Otherwise, we check to see if the user is a team member and process the request accordingly.
###Create ACL entries
ACLs are used to restrict access to application REST endpoints.
####ACL information
- Deny access to all project REST endpoints
- Select the model to apply the ACL entry to:
(all existing models) - Select the ACL scope:
All methods and properties - Select the access type:
All (match all types) - Select the role:
All users - Select the permission to apply:
Explicitly deny access
- Select the model to apply the ACL entry to:
- Allow unrestricted access to
GET /api/projects/listProjects- Select the model to apply the ACL entry to:
project - Select the ACL scope:
A single method - Enter the method name:
listProjects - Select the role:
All users - Select the permission to apply:
Explicitly grant access
- Select the model to apply the ACL entry to:
- Only allow admin unrestricted access to
GET /api/projects- Select the model to apply the ACL entry to:
project - Select the ACL scope:
A single method - Enter the method name:
find - Select the role:
other - Enter the role name:
admin - Select the permission to apply:
Explicitly grant access
- Select the model to apply the ACL entry to:
- Only allow team members access to
GET /api/projects/:id- Select the model to apply the ACL entry to:
project - Select the ACL scope:
A single method - Enter the method name:
findById - Select the role:
other - Enter the role name:
teamMember - Select the permission to apply:
Explicitly grant access
- Select the model to apply the ACL entry to:
- Allow authenticated users to access
POST /api/projects/donate- Select the model to apply the ACL entry to:
project - Select the ACL scope:
A single method - Enter the method name:
donate - Select the role:
Any authenticated user - Select the permission to apply:
Explicitly grant access
- Select the model to apply the ACL entry to:
- Allow owners access to
POST /api/projects/withdraw- Select the model to apply the ACL entry to:
project - Select the ACL scope:
A single method - Enter the method name:
withdraw - Select the role:
The user owning the object - Select the permission to apply:
Explicitly grant access
- Select the model to apply the ACL entry to:
$ slc loopback:acl
# follow the prompts, repeat for each ACL listed above
###Try the application
Start the server (node .) and open localhost:3000 in your browser to view the app. You will see logins and explanations related to each user type we created:
- Guest
Guest- Role = $everyone, $unauthenticated
- Has access to the "List projects" function, but none of the others
- John
Project owner- Role = $everyone, $authenticated, teamMember, $owner
- Can access all functions except "View all projects"
- Jane
Project team member- Role = $everyone, $authenticated, teamMember
- Can access all functions except "View all projects" and "Withdraw"
- Bob
Administator- Role = $everyone, $authenticated, admin
- Can access all functions except "Withdraw"