📜  struts 2双重验证示例(1)

📅  最后修改于: 2023-12-03 15:35:10.423000             🧑  作者: Mango

Struts 2双重验证示例

在Web应用程序中,表单提交过程中带有安全风险,因为它们可能包含有害代码,例如SQL注入攻击、跨站脚本等。为了减轻这些安全风险,Struts 2提供了一个双重验证(double validation)机制。

双重验证是指在客户端和服务器端都进行验证,以保证表单数据的有效性和完整性。客户端验证通过JavaScript代码根据预定规则在浏览器上检查表单数据。服务器端验证在表单数据被提交到服务器以后,对数据进行再次验证。

客户端验证

Struts 2提供了一系列客户端验证器,这些验证器会在表单提交前自动生成JavaScript代码。你可以通过在struts.xml中配置验证规则,来启用客户端验证:

<action name="Register" class="com.example.action.RegisterAction">
    <result name="success">/register.jsp</result>
    <result name="error">/register.jsp</result>
    <interceptor-ref name="defaultStack">
        <param name="validation.validateAnnotatedMethodOnly">true</param>
        <param name="validation.excludeMethods">input,back,cancel</param>
    </interceptor-ref>
    <interceptor-ref name="token"/>
</action>

在实际的表单页面中,你需要使用该标签引入包含客户端验证相关JavaScript的文件。

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Registration Form</title>
    <script type="text/javascript" src="/struts/xhtml/validation.js"></script>
</head>

然后,你需要在表单中使用Struts 2标记来指定要验证的字段和规则。

<s:form action="Register" method="post">
    <s:textfield name="username" label="Username"/>
    <s:password name="password" label="Password"/>
    <s:password name="confirmPassword" label="Confirm Password"/>
    <s:submit value="Submit"/>
    <s:token/>
</s:form>

在上面的例子中,我们定义了一个注册页面,其中包含了3个字段:用户名、密码、确认密码,以及一个用于提交表单的按钮。在表单的最后,我们使用<s:token/>标签添加了一个令牌,来防止CSRF攻击。

您可以在 action / com.example.action.RegisterAction 中编写方法来验证这些字段:

@Validations(
    requiredStrings={
        @RequiredStringValidator(fieldName = "username", message = "Username is required."),
        @RequiredStringValidator(fieldName = "password", message = "Password is required."),
        @RequiredStringValidator(fieldName = "confirmPassword", message = "Confirm Password is required.")
    },
    stringLengthFields={
        @StringLengthFieldValidator(fieldName = "username", minLength = "5", maxLength = "20", message = "Username length must be between 5 and 20."),
        @StringLengthFieldValidator(fieldName = "password", minLength = "8", maxLength = "20", message = "Password length must be between 8 and 20."),
        @StringLengthFieldValidator(fieldName = "confirmPassword", minLength = "8", maxLength = "20", message = "Confirm Password length must be between 8 and 20.")
    },
    regexFields={
        @RegexFieldValidator(fieldName = "username", regex = "^[a-zA-Z0-9]+$", message = "Invalid username."),
        @RegexFieldValidator(fieldName = "password", regex = "^[a-zA-Z0-9]+$", message = "Invalid password."),
        @RegexFieldValidator(fieldName = "confirmPassword", regex = "^[a-zA-Z0-9]+$", message = "Invalid confirm password.")
    },
    fieldExpressions={
        @FieldExpressionValidator(fieldName = "password", expression = "password == confirmPassword", message = "Passwords do not match.")
    }
)
public String execute() throws Exception {
    // your action logic here
}

在上面的例子中,我们使用@Validations注释来配置字段验证规则。我们使用requiredStrings验证器来检查所需的字段是否为空,使用stringLengthFields验证器来检查字符串长度,使用regexFields验证器来检查字符串的格式,使用fieldExpressions验证器来检查字段之间的关系。

服务器端验证

客户端验证是为了提高用户体验,在某些情况下如js出错、被注入等情况下,客户端数据可以被篡改,所以我们需要使用服务器端验证来保证数据的有效性。在客户端验证通过后,表单数据被提交到服务器以后,服务器再次验证数据的有效性。

服务器端验证与客户端验证相似,但是在Web浏览器端。您可以使用相同的验证器和方法来验证数据。 在验证过程中,您可以使用错误消息对象自定义错误消息。例如:

@Validations(
    requiredStrings={
        @RequiredStringValidator(fieldName = "username", message = "Username is required."),
        @RequiredStringValidator(fieldName = "password", message = "Password is required."),
        @RequiredStringValidator(fieldName = "confirmPassword", message = "Confirm Password is required.")
    },
    stringLengthFields={
        @StringLengthFieldValidator(fieldName = "username", minLength = "5", maxLength = "20", message = "Username length must be between 5 and 20."),
        @StringLengthFieldValidator(fieldName = "password", minLength = "8", maxLength = "20", message = "Password length must be between 8 and 20."),
        @StringLengthFieldValidator(fieldName = "confirmPassword", minLength = "8", maxLength = "20", message = "Confirm Password length must be between 8 and 20.")
    },
    regexFields={
        @RegexFieldValidator(fieldName = "username", regex = "^[a-zA-Z0-9]+$", message = "Invalid username."),
        @RegexFieldValidator(fieldName = "password", regex = "^[a-zA-Z0-9]+$", message = "Invalid password."),
        @RegexFieldValidator(fieldName = "confirmPassword", regex = "^[a-zA-Z0-9]+$", message = "Invalid confirm password.")
    },
    fieldExpressions={
        @FieldExpressionValidator(fieldName = "password", expression = "password == confirmPassword", message = "Passwords do not match.")
    }
)
public String execute() throws Exception {
    addActionError("Oops! Something went wrong.");
    return ERROR;
}

在上面的例子中,我们使用addActionError方法向错误消息对象添加一条错误消息,并在方法返回时返回错误视图。

结论

通过使用Struts 2的双重验证机制,您可以在Web应用程序中有效地减轻安全风险,同时提高表单提交的可靠性。客户端验证通过JavaScript代码在浏览器上验证表单数据,服务器端验证通过Java代码在Web服务器上再次验证表单数据。