在忘记密码页面中添加其他表单

时间:2012-05-14 22:40:31

标签: html forms cgi tcl

我有这个忘记的passowrd表单,它会检查用户名,如果有效,则会在他的电子邮件中发送临时密码。

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

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>"

1 个答案:

答案 0 :(得分:1)

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

  1. 将以前步骤中的数据放入短期(例如,可能是1小时?)的数据库记录中,并将记录密钥(UUID?)存储在会话cookie中。
  2. 将您之前步骤中的数据放入您发送给用户的表单中的隐藏字段(<input type="hidden">)中,以便以后处理。
  3. 这两种方法都非常适合您,前提是您在部署时拥有安全的通信渠道(在您的环境中设置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>
    }
    

    或者考虑使用html package in Tcllib进行模板化。这将在the Tcler's Wiki上进行更多讨论。