我正在创建一个网站,用户可以在其中注册、登录和注销。 我已经成功完成注册和登录,但是,我陷入了注销状态。
当用户登录时,会为该用户生成一个 jsonwebtoken,但是,我想在他们登录时显示注销按钮并隐藏登录按钮。目前,我已经能够通过 CSS 隐藏注销按钮。
此外,我不确定令牌是否确实附加到用户并且注销不起作用。
下面是我的代码:
服务器.js
const express = require('express');
const sqlite3 = require('sqlite3');
const bodyParser = require('body-parser');
const cors = require('cors');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const jwt = require('jsonwebtoken');
const PORT = 3000;
const app = express();
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use(express.json());
app.use(cors());
app.use(express.static('public'));
app.use(express.static('images'));
const db = new sqlite3.Database('database.db');
// Create a table for storing user data if it doesn't exist
db.run(`CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
firstName TEXT,
surname TEXT,
email TEXT,
password TEXT
)`);
app.get('/', (req, res) => {
res.json({"message":"Ok"});
});
// GET All Users
app.get('/users', (req, res) => {
// Retrieve all users from the database
db.all('SELECT * FROM users', (err, rows) => {
if (err) {
console.error('Error retrieving users:', err.message);
res.status(500).json({ error: 'Error retrieving users' });
} else {
// Send the user data as a JSON response
res.status(200).json(rows);
}
});
});
// Register a User
app.post('/register', (req, res) => {
const { firstName, surname, email, password } = req.body;
// Insert the user data into the database
db.run('INSERT INTO users (firstName, surname, email, password) VALUES (?, ?, ?, ?)',
[firstName, surname, email, password],
function(err) {
if (err) {
console.error('Error inserting user:', err.message);
res.status(500).json({ error: 'Error registering user' });
} else {
console.log(`User with id ${this.lastID} registered successfully`);
res.status(200).json({ message: 'User registered successfully' });
}
}
);
});
// Login a User
app.post('/login', (req, res) => {
const { email, password } = req.body;
// Check if the user with the provided email and password exists in the database
db.get('SELECT * FROM users WHERE email = ? AND password = ?', [email, password], (err, row) => {
if (err) {
console.error('Error during login:', err.message);
res.status(500).json({ error: 'Error during login' });
} else if (row) {
// User found, generate a JWT
// Set expiration time for the token - 1hr
const token = jwt.sign({ userId: row.id, email: row.email }, 'your-secret-key', { expiresIn: '1h' });
// User found, send a success response with user data
res.status(200).json({ message: 'Login successful', user: row, token });
console.log('Login successful', row);
} else {
// User not found or invalid credentials
res.status(401).json({ error: 'Invalid email or password' });
console.log('Invalid email or password');
}
});
});
app.get('/login', (req, res) => {
const { email, password } = req.query;
// Check if the user with the provided email and password exists in the database
db.get('SELECT * FROM users WHERE email = ? AND password = ?', [email, password], (err, row) => {
if (err) {
console.error('Error during login:', err.message);
res.status(500).json({ error: 'Error during login' });
} else if (row) {
// User found, send a success response
res.status(200).json({ message: 'Login successful' });
} else {
// User not found or invalid credentials
res.status(401).json({ error: 'Invalid email or password' });
}
});
});
// Logout User
app.get('/logout',(req,res) => {
req.logout();
req.session.destroy();
res.redirect('/')
});
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
signInScript.js
document.addEventListener('DOMContentLoaded', function() {
const emailInput = document.getElementById('signInEmailAddress');
const passwordInput = document.getElementById('signInPassword');
const submitButton = document.getElementById('submitButton');
const togglePasswordIcon = document.getElementById('togglePassword');
// Function to check if email and password fields are filled and enable/disable the submit button
function checkFormValidity() {
const isValid = emailInput.value.trim() !== '' && passwordInput.value.trim() !== '';
submitButton.disabled = !isValid;
}
// Function to handle password visibility toggle
function togglePasswordVisibility() {
const type = passwordInput.type === 'password' ? 'text' : 'password';
passwordInput.type = type;
togglePasswordIcon.classList.toggle('fa-eye-slash');
}
// Event listeners for input fields
emailInput.addEventListener('input', checkFormValidity);
passwordInput.addEventListener('input', checkFormValidity);
// Event listener for password visibility toggle
togglePasswordIcon.addEventListener('click', togglePasswordVisibility);
// Prevent form submission for demonstration purposes
document.getElementById("signInForm").addEventListener("submit", function(event) {
event.preventDefault();
const email = document.getElementById("signInEmailAddress").value;
const password = document.getElementById("signInPassword").value;
// Prepare data to be sent to the server
const data = {
email: email,
password: password
};
// Send data to the server using fetch API
fetch('/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(response => {
if (response.ok) {
// Login successful
return response.json(); // Parse the JSON response
} else {
// Login failed
console.error('Login failed');
// Show an error message to the user
alert("Login Failed!");
throw new Error('Login failed');
}
})
.then(data => {
// Access user data from the response
console.log('User data:', data.user);
// Redirect to another page or perform other actions with the user data
alert("Login Successful!");
console.log(data.token);
// Store the token in localStorage
localStorage.setItem('token', data.token);
})
.catch(error => {
console.error('Error:', error);
// Handle errors here
});
});
});
如有任何帮助,我们将不胜感激。
非常感谢。
您正在使用基于令牌的身份验证,而不是任何会话,因此您可以删除会话代码段。
当您在登录中返回 jwt 令牌时,保存它并在每个 api 调用中发送它,并在每个调用中进行验证,这就是令牌身份验证的工作原理。
并且令牌生成后,您无法手动过期。您无法使用 JWT 在服务器端注销。因此,从前端删除 jwt 以便它不能附加到任何请求是处理注销的方法。
如果你想通过jwt使用req.louout(),你可以使用passport包。
npm 安装护照
并且您可以将 jwt 令牌过期时间处理为 0。 然后你可以使用 jwt 注销。