我希望用户提供登录+密码来登录我的webapp。如果他失败了一段时间,验证码会起作用。 我想知道我该怎么办,从中删除java代码,并使其更具可读性 - 首先 - 安全吗?如果我将第二个'captch'ed'表单移动到不同的JSP(需要时由servlet调用) - 如何强制用户使用它?如何阻止通过'normal'login.jsp发送的数据?
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ page import="net.tanesha.recaptcha.ReCaptcha" %>
<%@ page import="net.tanesha.recaptcha.ReCaptchaFactory" %>
<!DOCTYPE html>
<html>
<head>
<title>User Login JSP</title>
<script lang="JavaScript">
function trim(s) {
return s.replace( /^\s*/, "" ).replace( /\s*$/, "" );
}
function validate() {
if(trim(document.frmLogin.userName.value)=="") {
alert("Login empty");
document.frmLogin.userName.focus();
return false;
}
else if(trim(document.frmLogin.userPassword.value)=="") {
alert("password empty");
document.frmLogin.userPassword.focus();
return false;
}
}
function validate() {
if(trim(document.frmLogin2.userName.value)=="") {
alert("Login empty");
document.frmLogin2.userName.focus();
return false;
}
else if(trim(document.frmLogin2.userPassword.value)=="") {
alert("password empty");
document.frmLogin2.userPassword.focus();
return false;
}
}
</script>
</head>
<body>
<%
Object failCounter = session.getAttribute("failCounter");
int fails = 0;
if (failCounter != null) {
fails = (Integer) failCounter;
}
if (fails < 3) {
%>
<form name="frmLogin" onSubmit="return validate();" action="validateLogin" method="post">
User Name <input type="text" name="userName" /><br />
Password <input type="password" name="userPassword" /><br />
<input type="submit" name="sSubmit" value="Submit" />
</form>
<%} else {
%>
<form name="frmLogin2" onSubmit="return validate2();" action="validateCaptcha" method="post">
User Name <input type="text" name="userName" /><br />
Password <input type="password" name="userPassword" /><br />
<%
ReCaptcha c = ReCaptchaFactory.newReCaptcha(PUBLIC_KEY, PRIVATE_KEY, false);
out.print(c.createRecaptchaHtml(null, null));
%>
<input type="submit" name="sSubmit2" value="submit" />
</form>
<%
}
%>
</body>
</html>
答案 0 :(得分:1)
我想知道我该怎么做,从中删除java代码,并使其更具可读性 - 首先 - 安全吗?
由于servlet不是一个选项,因此您必须求助于JSP包含。将以下内容添加到JSP的顶部:
<jsp:include page="/WEB-INF/loginAction.jsp" />
与
<%
if ("GET".equals(request.getMethod())) {
// Do here the job as you would in a normal servlet doGet() method.
// You only don't need to call RequestDispatcher#forward().
}
else ("POST".equals(request.getMethod())) {
// Do here the job as you would do in a normal servlet doPost() method.
// You only don't need to call RequestDispatcher#forward().
}
%>
让表单最终提交给自己,即删除action
。
这一堆JavaScript也可以重构为您在.js
中引用的独立<head>
文件。
<script src="validator.js"></script>
最后,你在表单的代码中重复自己。不要重复自己。
<form method="post" onsubmit="validate(this)">
User Name <input type="text" name="username" /><br />
Password <input type="password" name="password" /><br />
<% if (request.getAttribute("captcha") != null) { %>
Captcha <input type="text" name="captcha" /><br />
<img src="<%= request.getAttribute("captcha") %>" /><br />
<% } %>
<input type="submit" value="Submit" />
</form>
或者,如果您有机会使用JSTL,请执行
<form method="post" onsubmit="validate(this)">
User Name <input type="text" name="username" /><br />
Password <input type="password" name="password" /><br />
<c:if test="${not empty captcha}">
Captcha <input type="text" name="captcha" /><br />
<img src="${captcha}" /><br />
</c:if>
<input type="submit" value="Submit" />
</form>
此外,我无法理解安全点。请更具体一点。请注意,只要最终用户禁用JS,您的验证将无效。检查our servlets wiki page以获取服务器端验证示例。
如果我将第二个'captch'ed'表单移动到不同的JSP(需要时由servlet调用) - 如何强制用户使用它?如何阻止通过'normal'login.jsp发送的数据呢?
如果用户需要输入验证码,只需检查会话属性。
答案 1 :(得分:0)
感谢@BalusC,我设法将我的页面重构为:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>User Login JSP</title>
<script type="text/javascript" src="javascript/formDataValidator.js"></script>
</head>
<body>
<form name="frmLogin" onSubmit="return validate();" action="validateCaptcha" method="post">
User Name <input type="text" name="userName" /><br />
Password <input type="password" name="userPassword" /><br />
<c:if test="${ (sessionScope.failCounter != null) && (sessionScope.failCounter > 2 ) }">
<script type="text/javascript" src="http://api.recaptcha.net/challenge?k=6Ld9k8cSAAAAAB6jx0I_wu4f0n2zUL7QqYOC5JgM"></script>
</c:if>
<input type="submit" name="sSubmit" value="Submit" />
</form>
</body>
</html>
使用外部JS文件。
不需要使用scriptlet for captchha,所以我用out.print
内部创建的内容替换了它,它始终是相同的String =
脚本调用。
所以IMO值得做这个refacor:)