0

我有这个忘记密码的表格,它检查用户名,如果它有效,就会向他的电子邮件发送一个临时密码。

它工作正常,但我需要的是在我提交用户名后,我需要页面显示另一个表单,其中显示带有安全问题的表单,如果它有效,则创建临时密码并通过电子邮件发送。到目前为止,这是我的代码,我不知道在哪里添加新表单以及在哪里准确验证它。

HTML::cgi_read

    ###############################################################
    #   READ / VERIFY CGI VARIABLES
    ###############################################################
    SET_GLOBAL_VARS


    if { [catch {set REMOTE_ADDR        $CGI_DATA(REMOTE_ADDR)      } e] }  { set REMOTE_ADDR   "" }
    if { [catch {set HTTP_USER_AGENT    $CGI_DATA(HTTP_USER_AGENT)  } e] }  { set HTTP_USER_AGENT   "" }
    if { [catch {set COOKIE         $CGI_DATA(HTTP_COOKIE)      } e] }  { set COOKIE        "" }
    if { [catch {set MSG            $CGI_DATA(msg)          } e] }  { set MSG       "" }
    if { [catch {set USERNAME       $CGI_DATA(username)     } e] }  { set USERNAME      "" }
    if { [catch {set SECQUESTION        $CGI_DATA(secquestion)      } e] }  { set SECQUESTION   "" }
    if { [catch {set SECANSWER      $CGI_DATA(secanswer)        } e] }  { set SECANSWER     "" }

    ###############################################################
    #   ONLY ALLOW HTML START TO HAPPEN ONCE!
    #       Remember:   Redirects don't have HTML Start
    #               Meta Tags have to have it beforehand
    #               Cannot do both a redirect and a meta tag
    ###############################################################
    set HTMLSTARTFLAG 0
    proc HTML_START { } {
        global HTMLSTARTFLAG

        if {$HTMLSTARTFLAG < 1} {
            HTML::Start
            set HTMLSTARTFLAG 1
        }
    }

    ###############################################################
    #   START OF SCRIPT
    ###############################################################

    if {$USERNAME != ""} {
        ################################
        #   Do the hit for the entered user
        ################################
        set queryresult1 [InfxGetLogin $USERNAME]

        #any errors go back and show the blank login page
        if { [regexp -nocase "error" [lindex [split $queryresult1 ,] 0] ] } {
            set junk [InfxInsertLoginHistory $USERNAME "ForgotPassword" "$REMOTE_ADDR|$HTTP_USER_AGENT" "Error"]
            Redirect_Login "DB Error, Please try again."
            exit
        }

        set login   [lindex [lindex $queryresult1 0] 0]
        set locked  [lindex [lindex $queryresult1 0] 4]
        set dbquestion  [lindex [lindex $queryresult1 0] 5]
        set dbanswer    [lindex [lindex $queryresult1 0] 6]
        set emailTo [lindex [lindex $queryresult1 0] 7]
        set userId  [lindex [lindex $queryresult1 0] 8]

        ################################
        #   Validate user info
        ################################
        if {$login == ""} {
            set junk [InfxInsertLoginHistory $USERNAME "ForgotPassword" "$REMOTE_ADDR|$HTTP_USER_AGENT" "DoesNotExist"]
            Redirect_LoginForgotPass "Login Does Not Exist"
            exit
        }

        #locked people shouldn't get here, but if they do, they entered the page directly, send them away
        if {$locked == "t"} {
            set junk [InfxInsertLoginHistory $login "ForgotPassword" "$REMOTE_ADDR|$HTTP_USER_AGENT" "AcctLocked"]
            Redirect_LoginForgotPass "Account is Locked"
            exit
        }

        ################################
        #   Create temporary password
        #       Base64 encoding an rc4 encrypted text, then removing all special characters
        #       and taking the 1st 6 characters.
        ################################
        set pass [::base64::encode [rc4::rc4 -key [clock scan "now"] "randomizeme"]]
        regsub -all {[^a-zA-Z0-9]} $pass "" pass
        set pass [string range $pass 0 5]

        ################################
        #   Update DB w/ temporary password
        ################################
        set result [InfxResetUserPassword $userId $pass]

        if { $result != "ok" } {
            set junk [InfxInsertLoginHistory $login "ForgotPassword" "$REMOTE_ADDR|$HTTP_USER_AGENT" "Error"]
            Redirect_LoginForgotPass "DB Error, Please try again."
            exit
        }

        set result "ERROR"
        set result [HTML::mail "test@test.com $emailTo" "$emailFrom" "$emailSubj" "$emailMsg"]

        ################################
        #   Go back to login screen on success
        ################################
        if { $result == "0" } {
            Redirect_Login "Password Changed and Email Sent"
            exit
        } else {
            set junk [InfxInsertLoginHistory $login "ForgotPassword" "$REMOTE_ADDR|$HTTP_USER_AGENT" "EmailError"]
            Redirect_LoginForgotPass "Error Sending Email"
            exit
        }
    } else {
        ################################
        #   Initial display of username form
        ################################
        HTML_START

        puts {
        <head>
            <link rel="stylesheet" type="text/css" href="css/login.css" type="text/css">
            <script type="text/javascript" src="js/login.js"></script>

            <title> Services</title>

        </head>
        <body>
            <br><br>
            <img src="images/.gif" />
            <br><br><br>
            <div id="login">
                <form onsubmit="return validate_login_username(this)" action="login_forgotpw.cgi" method="post">
                    <table cellpadding="0" cellspacing="0">
                        <tr>
                            <th colspan="2"> Password Reset</th>
                        </tr>
                        <tr>
                            <td><label>Username:</label></td>
                            <td><input name="username"></input></td>
                        </tr>
                        <tr>
                            <td></td>
                            <td><input type="submit" value="Submit"></input></td>
                        </tr>
                    </table>
                </form>
            </div>
        }

    puts "  <h3 class=\"errormessage\">$MSG</h3>"

        exit
    }

这是表单,我想添加和验证,最好在同一页面中。

puts "<form action='login_forgotpw.cgi' method='post'>"
    puts "<td><label><b>Security Question : </b></td><td>$dbquestion ?</label></td></tr>"
    puts "<tr>"
    puts "<td><label><b>Answer:</b></td><td><input type='text' name='secanswer'></input></td>"
    puts "<td><input type='submit' value='Submit'></input></td>"
4

1 回答 1

1

一般来说,如果您正在执行多阶段表单,那么您可以通过以下两种机制之一将前面步骤中的数据向前传递:

  1. 将来自前面步骤的数据放入一个短暂的(例如,可能是 1 小时?)数据库记录中,并将记录密钥(一个 UUID?)存储在会话 cookie 中。
  2. 将来自先前步骤的数据放在<input type="hidden">您发送给用户以处理后续步骤的表单中的隐藏字段 ( ) 中。

这两种方法都非常适合您,前提是您在部署时有一个安全的通信通道(在您的环境中设置 HTTPS 完全超出了本讨论的范围)。我无法告诉您如何根据您的逻辑决定使用哪种形式;这取决于你知道而我不知道的约束。我可以说在上述两种实现技术之间,#1 的优点是它使整体消息更小,#2 的优点是它意味着更少的状态管理(因为所有状态都保留在客户端,直到你'准备好处理完全指定的密码更改)并且有人猜测会话密钥没有问题;我自己有点安全意识,我更喜欢使用隐藏字段。


生成表单时,分几个步骤进行:

puts {
<form ...>...blah static stuff
}
# Now a dynamic bit
puts "<input type='hidden' name='whatever' value='$whatever'>"
# Back to a static part
puts {
</form>
}

或者考虑使用Tcllib中的 html 包来做模板。Tcler's Wiki对此进行了更多讨论。

于 2012-05-16T10:16:42.397 回答