Следующее является частью кода Java при помощи фильтров, который показывает ошибочную страницу в каждый раз, если имя пользователя и пароль также корректны. Помогите мне, у меня нет большого знания об этом понятии.
String sql="select * from reg where username='"+user+"' and pass='"+pwd+"'";
rs=st.executeQuery(sql);
if(rs.next())
{
chain.doFilter(request,response);
}
else
sc.getRequestDispatcher("/error.html").forward(request,response);
String sql="select * from reg where username='"+user+"' и pass="+pwd+"";
Это крайне плохая практика. Такой подход требует, чтобы и имя пользователя, и пароль передавались по обычному ванилю через запросы. Более того, у вас есть дыра в SQL-инъекции атаки.
Используйте сессии, в JSP/Servlet есть HttpSession
for. Также нет необходимости снова и снова нажимать на БД при каждом запросе, используя Фильтр
. Это неоправданно дорого. Просто поместите User
в сессию, используя Servlet
, и используйте Filter
, чтобы проверить его присутствие на каждом запросе.
Начните с /логина. jsp
:
<form action="login" method="post">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit"> ${error}
</form>
Затем создайте LoginServlet
, который отображен на url-макетке
из /логина
и имеет следующую реализацию doPost()
:
String username = request.getParameter("username");
String password = request.getParameter("password");
User user = userDAO.find(username, password);
if (user != null) {
request.getSession().setAttribute("user", user); // Put user in session.
response.sendRedirect("/secured/home.jsp"); // Go to some start page.
} else {
request.setAttribute("error", "Unknown login, try again"); // Set error msg for ${error}
request.getRequestDispatcher("/login.jsp").forward(request, response); // Go back to login page.
}
Затем создайте LoginFilter
, который отображен на url-макетке
из /безопасной/*
(Вы можете выбрать свой собственный, однако, e. g. /защищенный/*
, /ограниченный/*
, /пользователи/*
и т.д., но это должно, по крайней мере, охватывать все защищенные страницы, вам также нужно поместить JSP в соответствующую папку в WebContent) и имеет doFilter()
, реализованный следующим образом:
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
String loginURI = request.getContextPath() + "/login.jsp";
boolean loggedIn = session != null && session.getAttribute("user") != null;
boolean loginRequest = request.getRequestURI().equals(loginURI);
if (loggedIn || loginRequest) {
chain.doFilter(request, response); // User is logged in, just continue request.
} else {
response.sendRedirect(loginURI); // Not logged in, show login page.
}
Это должно быть оно. Надеюсь, это поможет.
Чтобы получить представление о том, как будет выглядеть UserDAO
, вы можете найти эту статью полезной. Она также рассказывает о том, как использовать PreparedStatement
для спасения вашего веб-приложения от атак SQL инъекции.
Используйте подготовленное заявление, ваш код является открытым приглашением для SQL инъекции.
Connection con = getMyConnection();
try {
//no string concatenation, we use ? instead:
PreparedStatement ps = con.prepareStatement("select * from reg where username=? and pass=?");
try {
//actual value for parameters are set here:
ps.setString(1, user);
ps.setString(2, pwd);
ResultSet rs = ps.executeQuery();
if(rs.next()) {
chain.doFilter(request,response);
} else {
sc.getRequestDispatcher("/error.html").forward(request,response);
}
} finally {
ps.close();
}
} finally {
con.close();
}
Теперь, чтобы задать вопрос, пожалуйста, проверьте:
Во-первых, для этого действительно нужно использовать параметризованные запросы. Если пользователь в качестве имени пользователя введет '";DROP TABLE reg;
, то у вас будут большие проблемы.
Кроме того, вы уверены, что имя пользователя и пароль верны? Как насчет заглавной буквы?
.Столько всего неправильного... :-/
Выбор * из reg
не нужен, так как вы просто хотите знать, существует ли строка. Если бы вы использовали select 1
вместо этого, то БД не пришлось бы проверять содержимое строки и могла бы обслуживать результаты запроса только из индекса. Если вы ожидали, что будет много строк, то выберите 1, где существует ...
было бы быстрее, так как это позволило бы БД оборвать запрос после нахождения хотя бы одной строки.наконец
. Это означает, что они не гарантированно всегда будут располагаться (например, если брошен SQLException
), что приведет к утечке ресурсов и соединения.