Etano开源脚本登录改造求助:支持用户名/邮箱双方式登录
Hey there! Let's walk through how to modify the Etano script to let users log in with either their username or email. I'll break this down into actionable steps based on what you've shared:
First, double-check that your dsb_user_accounts table has both username and email fields, and that both are set with unique constraints. This prevents duplicate entries that could cause ambiguous login results. If you haven't added a unique index for email yet, run this SQL query:
ALTER TABLE dsb_user_accounts ADD UNIQUE KEY idx_email (email);
Adjust your login form to clarify that users can enter either a username or email. Keep the input field's name attribute the same (e.g., user) to minimize backend changes:
<div class="login-field"> <label for="user">Username or Email</label> <input type="text" id="user" name="user" required placeholder="Enter your username or email"> </div>
Here's how to update your existing POST handling code to support both login methods. We'll detect if the input is a valid email, then query the database accordingly:
if ($_SERVER['REQUEST_METHOD'] == 'POST') { // Get and sanitize the user input $user_input = strtolower(trim($_POST['user'])); // Check if the input is a valid email address $is_email = filter_var($user_input, FILTER_VALIDATE_EMAIL); // Prepare the database query based on input type if ($is_email) { // Sanitize email specifically to remove invalid characters $clean_input = filter_var($user_input, FILTER_SANITIZE_EMAIL); $sql = "SELECT * FROM dsb_user_accounts WHERE email = ? LIMIT 1"; } else { // Use Etano's existing sanitization for usernames $clean_input = sanitize_and_format_gpc($_POST, 'user', TYPE_STRING, 0, 0); $sql = "SELECT * FROM dsb_user_accounts WHERE username = ? LIMIT 1"; } // Execute the query (assuming Etano uses PDO for database access; adjust if using mysqli) $stmt = $db->prepare($sql); $stmt->execute([$clean_input]); $user = $stmt->fetch(PDO::FETCH_ASSOC); // Continue with password verification and login flow as before if ($user && password_verify($_POST['password'], $user['password_hash'])) { // Set user session, redirect to dashboard, etc. $_SESSION['user_id'] = $user['user_id']; header("Location: /dashboard.php"); exit; } else { // Show generic error to prevent credential enumeration $error = "Invalid username/email or password"; } }
Key Notes for This Code:
- Prepared Statements: We're using parameterized queries to avoid SQL injection—never concatenate user input directly into SQL.
- Case Insensitivity: Converting input to lowercase ensures consistency, since emails are case-insensitive by standard, and most usernames are treated as case-insensitive too (match your database collation, e.g.,
utf8mb4_general_ci). - Sanitization: We use email-specific sanitization for valid emails, and Etano's built-in sanitization for usernames to preserve existing rules.
- Generic Error Messages: Avoid telling users whether their input was a valid username/email or not—stick to a single "Invalid credentials" message to prevent attackers from enumerating valid accounts.
- Test Edge Cases: Verify login works with:
- Emails containing special characters (e.g.,
user+tag@example.com) - Usernames that look like emails but aren't valid (e.g.,
user@name) - Case variations (e.g.,
JohnDoevsjohndoefor usernames)
- Emails containing special characters (e.g.,
内容的提问来源于stack exchange,提问作者Don G.

