#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:
- guest
- owner
- team member
- administrator
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"