I am building an app using Express and Nodejs. I built client side using ejs templating language. So I was trying to make passport-jwt based authentication for it.
The backend is written in express was working perfectly. After user signed in or logged in, it issued a JWT and sent a JSON response to the frontend.
Now the frontend should theoretically be able to process this response and add the bearer token to local storage. But it doesn't work. Please check my code
I tried to debug using console.log statements in client side but none work :( Here's the Login.ejs:
<%- include('partials/head', { cssPath: '/css/login_styles.css' }) %>
<%- include('partials/navbar',{ cssPath: '/css/navbar.css' }) %>
<%- include('partials/flash') %>
<body>
<section>
<div class="container">
<div class="user signinBx">
<div class="imgBx"><img src="https://cdn.dribbble.com/users/8779526/screenshots/16963725/final-shot-5_4x.png" alt="" /></div>
<div class="formBx">
<form id="loginForm" method="POST">
<h2>Sign In</h2>
<input type="text" id="username" name="username" placeholder="Username" required>
<input type="password" id="password" name="password" placeholder="Password" required>
<input type="submit" value="Login">
<p class="signup">
Don't have an account ?
<a href="#" onclick="toggleForm();">Sign Up.</a>
</p>
</form>
</div>
</div>
<div class="user signupBx">
<div class="formBx">
<form action="/signup" method="POST">
<h2>Create an account</h2>
<input type="text" name="username" placeholder="Username" required>
<input type="password" name="password" placeholder="Create Password" required>
<input type="submit" name="" value="Sign Up">
<p class="signup">
Already have an account ?
<a href="#" onclick="toggleForm();">Sign in.</a>
</p>
</form>
</div>
<div class="imgBx"><img src="https://image.freepik.com/free-vector/privacy-policy-protecting-your-privacy_126283-816.jpg" alt="" /></div>
</div>
</div>
</section>
<script src="/scripts/login.js"></script>
<script>
const toggleForm = () => {
const container = document.querySelector('.container');
container.classList.toggle('active');
};
document.getElementById('loginForm').addEventListener('submit', async function(event) {
event.preventDefault(); // Prevent the form from submitting normally
// Fetch the form data
const formData = new FormData(this);
const username = formData.get('username');
const password = formData.get('password');
console.log(formData);
const response = await fetch('/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ username, password })
});
const data = await response.json();
console.log(data);
if (data.success) {
localStorage.setItem('token', data.token);
localStorage.setItem('expiresIn', data.expiresIn);
window.location.href = data.redirect;
} else {
alert(data.msg);
}
});
</script>
</body>
Here's the client side script for handling response. I wrote it in the ejs file itself for easier debugging.
Here's the routing and backend logic for the login and sign up:
app.post('/signup', async (req, res) => {
try {
const { username, password } = req.body;
const user = new User({ username });
const registeredUser = await User.register(user, password);
// Issue JWT
const jwtToken = issueJWT(registeredUser);
console.log('User logged in successfully after signup:', registeredUser);
console.log('User jwt: ', jwtToken);
// Send JSON response
res.status(200).json({
success: true,
msg: "Account created successfully!",
token: jwtToken.token,
expiresIn: jwtToken.expiresIn,
redirect: '/' });
} catch (e) {
console.error("Error during signup:", e);
res.status(500).json({ success: false, msg: "There appears to be a problem." });
}
});
app.post('/login', passport.authenticate('jwt', { session: false }), (req, res) => {
try {
const tokenObject = issueJWT(req.user); // Assuming req.user is populated by passport-local-mongoose
return res.status(200).json({
success: true,
msg: 'Logged in successfully',
token: tokenObject.token,
expiresIn: tokenObject.expiresIn,
redirect: '/',
});
} catch (err) {
console.error('Error during login:', err);
return res.status(500).json({ success: false, msg: 'Internal server error' });
}
});
Forgive in advance for any mistakes in question formatting as this is my first question ^_^
I tried to debug using console.log statements in ejs file script but I found that none work. That means that client-side script likely isn't being executed.