General Instructions
In this homework: We will protect passwords via secure hashes, enable club member login via “sessions”, customize menus for different users, and protect sensitive information from modification or access. Put any code you write for this homework into the clubServer
directory except for problem 5 which will go into a new top level directory called clubReact
.
Create and Use a new Branch hw10
We will create a new git branch called hw10
(starting from your ‘hw9’ branch) for use in this assignment. The branch you create must exactly match the one I’ve given you for you to receive any credit for this homework.
Prior to creating this new branch make sure your working directory is “clean”, i.e., consistent with the last commit you did when you turned in homework 9. Follow the procedures in GitHub for Classroom Use to create the new branch, i.e., git checkout -b hw10
. Review the section on submission for using push with a new branch.
Use README.md
for Answers
You will modify the README.md
file to contain the answers to this homework.
# Homework #10 Solution
**Your name** **NetID: yourNetID**
Questions
Question 1. (10 pts) Securing User Passwords
For this question you will need the mock user data I generated: clubUsers2.json. Put all work in your clubServer
directory.
(a) Hash user passwords
To emulate server side storage of user information including passwords, write a Node.js program that reads in the clubUsers
data from JSON, hashes the password field with bcrypt, and saves the data to a new file clubUsersHash.json
.
Hint you can use the following code to get you started if you like.
const fs = require('fs');
const bcrypt = require('bcryptjs');
const users = require('./clubUsers2.json');
let nRounds = 10;
let hashedUsers = [];
let start = new Date(); // timing code
console.log(`Starting password hashing with nRounds = ${nRounds}, ${start}`);
// Your code here to process the passwords
let elapsed = new Date() - start; // timing code
console.log(`Finished password hashing, ${elapsed/1000} seconds.`);
.writeFileSync("clubUsersHash.json", JSON.stringify(hashedUsers, null, 2)); fs
Show your code here along with a couple of entries from the clubUsersHash.json
file.
(b) bcrypt work
By changing the “rounds” parameter to bcrypt
we can make it harder (in terms of computation) to compute the password hash and thus increase our defenses a bit. Using the program from part (a) increase the number rounds (default is 10) parameter to bcrypt until it takes at least 15 seconds to run. Take a screen shot of the timing results. I get something like:
(c) Handle Member Application Password
Fix your handler from HW#9 problem 3(b) to create a secure hash of the password from the membership application for storage on the server. Show your updated handler code here. Here is a screen shot showing browser view and server debug output.
Question 2. (10 pts) Login POST Form
Note: By the time we are through securing our website the login handler function will be our most complicated route handler function. Try to keep your code as clean and readable as possible to avoid confusion and debugging nightmares.
(a) Update Login page/template to Form
Update your login template to submit a POST form to the server. Choose an appropriate action
URL. Show just the form portion of the template here.
(b) Handle Post and Verify Password
We will use the clubUsersHash.json
file as our “database” of users on the server. So import this into a global variable onto the server. Create a handler for the POST form that looks up the user by email (use JS array method) and verifies (or not) the users password using bcryptjs. For now just send any response you like back to the client.
Show your handler code here.
(c) Send Problem
Create a simple “login problem” page/template to send in the case the password is not verified. Show a screen shot. Mine looks like:
(d) Send Welcome
Create a simple “welcome” page/template to send in the case the password is verified. Show a screen shot. Mine looks like
Question 3. (10 pts) Add Activity GET Form
(a) Create Add Activity Page/Template
Create a page to add a club activity via a GET form. Add a menu item to show this page and a route handler to the server. Show a screen shot of this page/template including the updated menu. I get something like:
(HW10Sp21Prob3a.png)
Note: No extra CSS is required.
(b) Handle GET form Submission
Create a route handler to add the activity to the list of events/activities stored in a global variable on the server (do not save to a file!), then redirect to the “activities” page so that you can see that the activity was added. Temporarily limit the maximum number of activities to 100. Hint: use a simple test like:
if (eventData.length > 100) { // only keep the last 100 activities added
.shift(); // removes the first item
eventData }
Show your handler code here.
Question 4. (10 pts) Session Login/Logout
You are now going to implement full login/logout capabilities for your site in a manner similar to that shown in the Express Sessions course slides. However our minimal starting session state will be {"role": "guest"}
. Remember to install express-session
in a way that keeps your package.json
file up to date.
(a) Implement Session Based Login
Appropriately import and initialize express-session
middleware. Add session state initialization code for our club. Use appropriate mechanisms to update session when a user successfully logs in. Show your /login
handling code here. Also make sure for failed logins to return a 400 “bad request” code with the response.
(b) Implement Session Based Logout
Add a GET /logout
path to your server (and a logout menu item) to destroy the “session” and “clear” the cookie as done in the course slides. Show your /logout
handling code here.