After this lesson, you will be able to:
- Create an API that will serve contents from a database to an Angular app.
- Create an angular application that will use an API to send and receive information form a Mongo Database.
- Fork this repo
- Clone your fork into your
~/code/labs
folder.
Upon completion, run the following commands:
$ git add .
$ git commit -m"done"
$ git push origin master
Navigate to your repo and create a Pull Request from your master branch to the original repository master branch.
In the Pull Request name, add your campus, name, and last name separated by a dash "-".
In this lesson you have to deliver two different projects: the server API and the client. You can add the client folder in the server folder to keep both in the same repo.
We all have secrets, wouldn't it be nice if we had a reliable way to store our secrets in a secure way? We are going to build an application that will allow us to store our biggest secrets.
In the repo you have forked, we provide you some code in the starter code folder. This code has the main structure for the API and the Client app you are going to build.
We have already generated and added all the packages you will need to start working in your API. The folder structure is the following:
starter-code/
├── client
│ └── src
│ └── app
│ │ ├── app.component.css
│ │ ├── app.component.html
│ │ ├── app.component.ts
│ │ └── app.module.ts
│ └── auth-login
│ │ ├── auth-login.component.css
│ │ ├── auth-login.component.html
│ │ └── auth-login.component.ts
│ └── signup-login
│ │ ├── auth-signup.component.css
│ │ ├── auth-signup.component.html
│ │ └── auth-signup.component.ts
│ └── my-private-page
│ │ ├── my-private-page.component.css
│ │ ├── my-private-page.component.html
│ │ └── my-private-page.component.ts
│ └── session-service.ts
├── .gitignore
├── app.js
├── bin
│ └── www
├── configs
│ └── passport.js
├── models
│ └── user.js
├── package.json
├── public
└── routes
As you can see, the project has a client
folder where you will find all the necessary files to create your angular app. It already has all the components and the service provided for you. Moreover, the main folder has the structure to create the API that will use the Angular app.
The first thing we have to create is the API. Remember to install all the packages before beginning.
The User model will have the following fields:
username
, string. We will use it to login.password
, string. Encrypted withbcrypt
, we will use it with the username to authenticate the user.name
, string. It will store the user full name.secret
, string. In this field, we will store our secret.
Remember to add the timestamps createdAt
and updatedAt
to the model, to store those values as well.
You have to add the code into the models/user.js
file to generate your model.
Tasks
Create the model in the model/user.js
file, with the following fields:
username
password
name
secret
createdAt
updatedAt
The following step is to configure Passport.js to use the Local Strategy to authenticate users. You can find the functions you have to complete in the config/passport.js
file. Remember we will use this service from our Client app.
Tasks
Add the necessary code to configure Passport.js, by completing the following functions:
passport.use()
passport.serializeUser()
passport.deserializeUser()
To finish up with our API, we have to create the various routes we will call from the client. You can find the routes in the routes/authController.js
. We have already generated the main structure of your routes, you just have to create the code.
The controller contains the following methods:
POST /signup
, that will receive the user information to signup in our application. Once we have stored the information in the database, we have to automatically login the user with thereq.login
method.POST /login
, that will receive the username and the password, and start a session if the data is correct. If the data is incorrect, it has to throw an exception.POST /logout
, that will finish the user session.
Note: You are creating an API. Remember to return not just the data, but also the Status Code that corresponds to the action that the user has done.
You can check out the different status codes you can return in the Status Cats API website.
Tasks
Generate the necessary code to implement your API in the routes/authController.js
file:
POST /signup
.POST /login
.POST /logout
.
Once we're done with the API, we can start coding the client. Remember that you will have to generate the necessary files with $ ng build --prod
and add all the generated files in the client/build
folder to the /public
folder of the server.
The first thing we will focus on with the client-side is the service that we will use to call our API methods. You have to change the file in client/src/app/session.service.ts
file.
We will have to create different methods to call the corresponding routes in the API. We need to create the following methods:
signup()
, that will receive as a parameter the user data that will be stored in the database. If the information is correct, we will assign the user session to theuser
variable we will define.login()
, that will receive the username and password to check out if the credentials are correct and will start a session. Once the session starts, we have to store the current user in theuser
variable.isLogged()
will return if there is a user logged in or not. We will use theuser
variable in the session to do that.logout()
will finish the session, and remove the current user information from the variable in the service.handleError()
will receive an error as a parameter and return an Observable with the message of the error.
Once we have done all this, we will have all the service correctly implemented.
Tasks
Create the necessary code to create a service that we will use to call the methods we have defined in the API. We have to:
- Create a
user
variable to store the current user information. - Generate the code of the following functions described above:
handleError()
signup()
login()
isLogged()
logout()
The following step in our process is to generate the routes that we will use to show the different components. We will have three different routes:
/signup
/login
/private
The components are already in the project, so you just have to add the routes into the client/src/app/app.module.ts
file that will render the correct component depending on the route.
Tasks
Change the client/src/app/app.module.ts
file to add the routes, by doing the following:
- Add the
RouterModule
andRoutes
modules form@anguler/router
. - Create a
Routes
array, with the following routes:signup
, that will renderAuthSignupComponent
.login
, that will renderAuthLoginComponent
.private
, that will renderMyPrivatePageComponent
.
- Add the array to the
imports
section in the file.
The app.component
will be super simple. It will have two links (login
and signup
) if the user is not logged in, and a button (logout
) if the user is logged in. You should use an ngIf
directive to do that. You also have to style the page.
Tasks
Change the app.component.html
and app.component.ts
files to do the following:
- If a user is not logged in, show two different links that will render different components:
login
, that will renderAuthLoginComponent
.signup
, that will renderAuthSignupComponent
.
- If a user is logged in, show a button to
logout
.
Once the user is in the /signup
page, we have to show them a form that will allow them to create a new account in the database. We have defined our model with four different fields: username
, password
, name
, and secret
.
We are saving our secret, so we don't want people to see what it is while we're filling in the form. Use a password
input field in the form.
When we click on the Signup
button, we have to use the service we built in Iteration 4 to store the user information in the database.
Tasks
Create the necessary changes in the code to allow users to signup in our application:
auth-signup.component.html
file, create the form with the following fields:username
, type text.password
, type password.Full name
, type text.secret
, type password.
auth-signup.component.ts
file, add the following:formInfo
object, to store all the information of the form.error
, to store the error it could be generated during the signup process.signup()
method to handle the request.
- Once the user has signed up, we start the session automatically, so we have to redirect the user to the
/private
page.
The login component has to have all the necessary fields to start a new session, so we have to create a form with username and password.
Again, when we click on the Login
button, we have to use the service we built in the Iteration 4 to recover the data from the database and check if the login succeeded or not.
Tasks
auth-login.component.html
file, create the form with the following fields:username
, type text.password
, type password.
auth-login.component.ts
file, add the following:formInfo
object, to store all the information of the form.error
, to store the error it could be generated during the signup process.login()
method to handle the request.
- Once the user has logged in, we have to redirect them to the
/private
page.
To finish up this exercise, we have to load the user information and show it on the page. We will basically show the user's secret. We will use the user information we have in the Session
service we created before.
The user has to be logged in to access this page. If they are not logged in, we have to redirect them to the login page.
Tasks
my-private-page.component.html
file, show the user's secret with an interpolation.my-private-page.component.ts
file, subscribe the component to theSession
service to be able to load the user secret.- If the user is not logged in, redirect them to the login page when they try to access this page.
/Happy coding!