首先我要说的是,我不是一个专业的开发人员,这只是我出于兴趣和太多空闲时间而学习做的事情。我是一个初学者,我需要把这个问题弄清楚,以防我因为问了这么简单的问题而被抨击。
我试图使一个“选择你自己的冒险”网页游戏,纳入一个登录功能的实践。我使用的是Eclipse Mars,运行在Tomcat8.0上。我在MySql数据库中创建了一个名为PLAYER的表,其中包含id、用户名和密码字段。到目前为止,我已经创建了以下文件: index.html (存放登录表单)、menu.html (成功登录后的登录页面)和Login.java (处理数据库连接和用户身份验证的servlet )。
下面是index.html的一部分:
<form method="post" action="Login">
<div class="form_layout">
<label>User name:</label>
<input type="text" id="uname" style="width:100%"/>
<label>Password:</label>
<input type="password" id="pword" style="width:100%"/>
<input type="submit" id="login_btn" value="LOGIN" />
</div>
</form>以下是Login.java的全部内容:
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.*;
@WebServlet("/Login")
public class Login extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("uname");
String password = request.getParameter("pword");
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost/game"+"?verifyServerCertificate=false"+"&useSSL=true";
String user = "root";
String pass = "password";
String sql = "SELECT username, password FROM player WHERE username = ? AND password = ?";
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
boolean login = false;
try {
Class.forName(driver);
connection = DriverManager.getConnection(url, user, pass);
statement = connection.prepareStatement(sql);
statement.setString(1, username);
statement.setString(2, password);
resultSet = statement.executeQuery();
login = resultSet.next();
} catch (Exception e) {
throw new ServletException("Login failed", e);
} finally {
if (resultSet != null) try { resultSet.close(); } catch (SQLException ignore) {}
if (statement != null) try { statement.close(); } catch (SQLException ignore) {}
if (connection != null) try { connection.close(); } catch (SQLException ignore) {}
}
if (login) {
request.getSession().setAttribute("username", username);
response.sendRedirect("menu.html");
} else {
request.setAttribute("message", "Unknown username/password, try again");
request.getRequestDispatcher("index.html").forward(request, response);
}
}
}每次我尝试登录时,我总是被重定向到index.html,无论我输入的凭据是否正确。我试着改变这个:
else {
request.setAttribute("message", "Unknown username/password, try again");
request.getRequestDispatcher("index.html").forward(request, response);
}要这样做:
else {
request.setAttribute("message", "Unknown username/password, try again");
request.getRequestDispatcher("menu.html").forward(request, response);
}来查看重定向是否正常工作,并发现它绕过了if语句,直接转到else。我猜'login‘没有返回true,这就是为什么它不会按照我想要的方式重定向。看看现在的代码,我真的不知道我做错了什么。我已经在互联网上寻找答案了,但我想不出任何办法来解决这个问题。
任何形式的帮助都将不胜感激。谢谢!
发布于 2015-12-14 01:18:56
(这不是对你问题的直接回答,但我没有足够的声誉来评论)
由您自己实现登录存在安全风险。用户可以输入/menu.html url并在没有登录的情况下看到页面(“深度链接”)。这里的另一个问题是明文密码的存储。最好是保存一个哈希表。
Tomcat提供了一个登录机制:https://tomcat.apache.org/tomcat-8.0-doc/realm-howto.html
在web.xml中,您可以定义受保护区域,只有经过身份验证的用户才能访问这些区域。对于身份验证,您可以使用JDBCRealm,它在数据库中执行用户查找。
发布于 2015-12-20 00:39:57
解决了这个问题。查询是正确的,但是ResultSet返回为空,因为由于某种原因,来自input name = "pword“的值无法读取(当我试图将其值打印到控制台时,返回null ),因此在数据库中找不到匹配。我认为这与输入类型密码有关(这很奇怪,因为它应该是这样工作的)。我所做的是将输入类型更改为文本,这样就行了,除了表单上的密码字段中的字符可以看到之外。把它改回了input type = password,这解决了我的问题。不知道为什么会这样,但是重定向现在起作用了。感谢所有帮助过我们的人!
发布于 2015-12-14 01:39:19
我还发现了另一件事:表单中的输入元素没有名称。servlet尝试通过它们的id从请求中获取它们,但是在请求中提交的是输入元素的名称。
过时的(错误的)想法:
我想我现在发现了错误:您正在将查询中的字符串与sql中的"=“进行比较,它类似于...
String sql = "SELECT username, password FROM player WHERE username LIKE ? AND password LIKE ?";https://stackoverflow.com/questions/34253628
复制相似问题