So Basically what I want to achieve here is to allow logged in users to access pages that their role/access level allows them to while preventing those with a lesser or different roles from accessing the higher access pages (EX. obviously I don’t want students to be messing around with the library’s database and thus this privilege/access to the webpage with that function is reserved for teachers and above) Additionally I also don’t want users that aren’t logged in from accessing anything other than the sign up and login page.
So far I have some basic infrastructure here on the backend which writes the users access level on their token upon logging in:
const express = require('express');
const router = express.Router();
const mysql = require('mysql');
const bodyParser = require('body-parser');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken'); // Import jsonwebtoken for token generation
const connection = require('../database/connector');
const config = require('../Misc/Config');
router.use(bodyParser.json());
// Define the login route
router.post('/login', (req, res) => {
const { username, password } = req.body;
// Check if the username and password are provided
if (!username || !password) {
res.status(400).json({ error: 'Username and password are required.' });
return;
}
// Query the database to find the user by username
const sql = 'SELECT * FROM accounts.loginfo WHERE username = ?';
connection.query(sql, [username], async (error, results) => {
if (error) {
console.error(error);
res.status(500).json({ error: 'An error occurred during login.' });
} else {
// Check if the user exists
if (results.length === 0) {
res.status(401).json({ error: 'Invalid username or password.' });
} else {
// Verify the password
const user = results[0];
const passwordMatch = await bcrypt.compare(password, user.password);
if (!passwordMatch) {
res.status(401).json({ error: 'Invalid username or password.' });
} else {
// User is authenticated; create a JWT token and send it back to the client
const token = generateAuthToken(user);
// Include the user's access level in the response
res.status(200).json({ token, access: user.access });
}
}
}
});
});
// Function to generate a JWT token
function generateAuthToken(user) {
// Generate a JWT token with user data and a secret key
const token = jwt.sign({ userId: user.id, username: user.username }, config.secretKey, { expiresIn: '1h' });
return token;
}
module.exports = router;
Here is the corresponding log in front end:
// Wait for the DOM to load
if (document.readyState == 'loading') {
document.addEventListener('DOMContentLoaded', ready);
} else {
ready();
}
function ready() {
const loginpassword = document.getElementById('loginpassword');
const togglePasswordButton = document.getElementById('ShowPass');
togglePasswordButton.addEventListener('click', function () {
if (loginpassword.type === 'password') {
loginpassword.type = 'text';
} else {
loginpassword.type = 'password';
togglePasswordButton.textContent = 'Show Password';
}
});
// Add event listener to the Login button
const loginButton = document.getElementById('Login');
loginButton.addEventListener('click', () => {
const username = document.getElementById('loginuser').value;
const password = document.getElementById('loginpassword').value;
// Validate user input
if (!username || !password) {
alert('Please enter your username and password.');
return;
}
// Create an object with login data
const loginData = {
username,
password,
};
// Send a POST request to the backend login route
fetch('/api/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(loginData),
})
.then((response) => response.json())
.then((data) => {
if (data.error) {
// Display an error alert if login fails
alert('Login failed. Please check your username and password.');
} else {
// Store the token securely in localStorage
localStorage.setItem('authToken', data.token);
// Determine where to redirect based on user's access
if (data.access === 'teacher') {
window.location.href = '../Teacher-Pages/T-Home.html'; // Teacher dashboard URL
} else if (data.access === 'student') {
window.location.href = '../Student-Pages/S-Home.html'; // Student dashboard URL
} else {
alert('Invalid user access.'); // Handle other access types as needed
}
}
})
.catch((error) => {
console.error(error); // Log the error for debugging
alert('An error occurred during the login process.');
});
});
}
Both of these JS does work and i have tested and logged if a token i create when a user logs in, and it does. but i am at a loss how to proceed with the Role Based Access System, i am fairly new to full stack web dev so any help would be appreciated.
Here is my app.js:
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
// Import the signup and login routes
const signupRoute = require('./routes/signup');
const loginRoute = require('./routes/login'); // Import your login route
const logoutRoute = require('./routes/logout')
// Serve static files from the 'public' directory
app.use(express.static('public'));
// Middleware to parse incoming JSON data
app.use(bodyParser.json());
// Use the signup and login routes with their respective prefixes
app.use('/api', signupRoute);
app.use('/api', loginRoute); // Add the login route
app.use('/api', logoutRoute);
// Start the server
const port = process.env.PORT || 3002;
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});