⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 username-password database for tclhttpd.mht

📁 TCL的数据库处理支撑库及一些示例
💻 MHT
📖 第 1 页 / 共 3 页
字号:
From: =?gb2312?B?08kgV2luZG93cyBJbnRlcm5ldCBFeHBsb3JlciA3ILGjtOY=?=
Subject: Username/Password Database for Tclhttpd
Date: Fri, 29 Feb 2008 00:32:55 +0800
MIME-Version: 1.0
Content-Type: multipart/related;
	type="text/html";
	boundary="----=_NextPart_000_0081_01C87A6A.A0310BB0"
X-MimeOLE: Produced By Microsoft MimeOLE V6.0.6000.16545

这是 MIME 格式的多方邮件。

------=_NextPart_000_0081_01C87A6A.A0310BB0
Content-Type: text/html;
	charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Content-Location: http://wiki.tcl.tk/8657

=EF=BB=BF<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" =
"http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<HTML lang=3Den><HEAD><TITLE>Username/Password Database for =
Tclhttpd</TITLE>
<META http-equiv=3DContent-Type content=3D"text/html; charset=3Dutf-8">
<STYLE type=3Dtext/css media=3Dall>@import url( /wikit.css );
</STYLE>
<LINK title=3DRSS href=3D"/rss.xml" type=3Dapplication/rss+xml =
rel=3Dalternate><!--[if lte IE 6]>=0A=
		<style type=3D'text/css' media=3D'all'>@import 'ie6.css';</style>=0A=
	<![endif]--><!--[if gte IE 7]>
<STYLE type=3Dtext/css media=3Dall>@import url( ie7.css );
</STYLE>
<![endif]-->
<SCRIPT type=3Dtext/javascript>=0A=
	    function init() {=0A=
		// quit if this function has already been called=0A=
		if (arguments.callee.done) return;=0A=
=0A=
		// flag this function so we don't do the same thing twice=0A=
		arguments.callee.done =3D true;=0A=
=0A=
		try {=0A=
		    checkTOC();=0A=
		} catch (err) {=0A=
		    /* nothing */=0A=
		}=0A=
	    };=0A=
=0A=
	    /* for Mozilla */=0A=
	    if (document.addEventListener) {=0A=
		document.addEventListener("DOMContentLoaded", init, false);=0A=
	    }=0A=
=0A=
	    /* for Internet Explorer */=0A=
	    /*@cc_on @*/=0A=
	    /*@if (@_win32)=0A=
	    document.write("<script defer src=3Die_onload.js><\/script>");=0A=
	    /*@end @*/=0A=
	    =0A=
	    /* for other browsers */=0A=
	    window.onload =3D init;=0A=
	</SCRIPT>

<META content=3D"MSHTML 6.00.6000.16609" name=3DGENERATOR></HEAD>
<BODY>
<DIV class=3Dcontainer>
<DIV class=3Dheader>
<DIV class=3Dlogo><A class=3Dlogo =
href=3D"http://wiki.tcl.tk/">wiki.tcl.tk</A> </DIV>
<DIV class=3Dtitle id=3Dtitle><A title=3D"click to see 2 references to =
this page"=20
href=3D"http://wiki.tcl.tk/_ref/8657">Username/Password Database for=20
Tclhttpd</A></DIV>
<DIV class=3Dupdated id=3Dupdated>Updated 2005-06-15 14:21:22 <A =
class=3Ddelta=20
href=3D"http://wiki.tcl.tk/_diff/8657#diff0">=E2=96=B2</A></DIV></DIV>
<DIV id=3Dwrapper>
<DIV id=3Dcontent>
<P>The following example shows a username/password database for <A=20
href=3D"http://wiki.tcl.tk/2085">Tclhttpd</A>. It uses the following</P>
<UL>
  <LI>Metakit for the database=20
  <LI>logic and code from the <A =
href=3D"http://wiki.tcl.tk/6137">formkit</A>=20
  package=20
  <LI><A href=3D"http://wiki.tcl.tk/1070">crypt in pure tcl</A> from the =
wiki for=20
  the passwords=20
  <LI>The Tclhttpd session module for row(record) locking and session=20
  control.</LI></UL>
<P><B>***</B> 10 July 2003 <A href=3D"http://wiki.tcl.tk/6132">Jeff =
Smith</A> <I>A=20
<A href=3D"http://wiki.tcl.tk/3661">Starkit</A> with a few extra =
features can be=20
found at</I> [<A href=3D"http://www.freewebs.com/headsup/userpassdb.htm" =

rel=3Dnofollow>1</A>] <B>***</B></P>
<P>Create a "dbdata" directory under the Doc_Root directory (usually=20
htdocs).</P>
<P><B>The following files are all saved to the custom directory in=20
Tclhttpd.</B></P>
<P>Get the <A href=3D"http://wiki.tcl.tk/1070">crypt in pure tcl</A> =
package and=20
save it to tclcrypt.tcl Change the proc name from crypt to tclcrypt. =
This is to=20
avoid name conflicts as Tclhttpd looks for the unix crypt.</P>
<P>Edit the first line and change it from</P><PRE> proc crypt {password =
salt} {</PRE>
<P>to</P><PRE> proc tclcrypt {password salt} {</PRE>
<P>Save the following</P>
<H4>******** Begin fmkt.tcl =
********************************************</H4><PRE> # This an example =
of a username/password database for the Tclhttpd webserver.
 # It uses Metakit for the database and uses ideas from formkit for
 # row or record locking. It uses the session module from Tclhttpd for =
session
 # control and crypt in pure tclfrom the wiki.

 # Set up the Database

 mk::file open users [Doc_Root]/dbdata/users.dat

 mk::view layout users.details {user longname location phone email pass =
}

 # Register Document type handler.

 Mtype_Add .fmkt application/x-tcl-fmkt

 # Set the start page that is used to launch a new session.

 set Fmkt(startpage) /start.tml

 # Set the time in seconds that a session will last for.

 set Fmkt(age) 300

 proc Doc_application/x-tcl-fmkt {path suffix sock} {
     upvar #0 Httpd$sock data
     global Fmkt

     append data(query) ""
     set queryList [Url_DecodeQuery $data(query)]

     # Destroy any old session that are laying around. In this instance
     # 5 minutes is the setting.

     Session_Reap $Fmkt(age) Fmkt

     # Find the current session (or start a new one if session=3Dnew).

     set session [Session_Match $queryList Fmkt error]

     if {$session =3D=3D {}} {
         Fmkt_ErrorPage $sock "The session no longer exists!  $error"
         return
     }

     # Process the query data from the previous page.

     if [catch {FmktProcess $session $queryList} result] {
         Httpd_ReturnData $sock text/html $result
         return
     }
     # Expand the page in the correct session interpreter, or treat
     # the page as ordinary html if the session has ended.

     switch -exact -- $result {
         0 { Httpd_ReturnFile $sock text/html $path }
         1 { Doc_Subst $sock $path interp$session }
         2 { Fmkt_ErrorPage $sock "This record locked by another user!" =
}
         3 { Fmkt_ErrorPage $sock "Must enter a character!" }
         4 { Fmkt_ErrorPage $sock "Record has been saved!" }
     }
 }

 # The purpose of this procedure is to process the form query data.
 # Based on the query data certain procedures are triggered.
 # Parameters
 #   session:  the session id
 #   query:    a list of names and values produced by Url_DecodeQuery

 proc FmktProcess {session query} {
     global Fmkt
     upvar #0 Session:$session state
     set interp $state(interp)

     # Process each query item.
     # Some items, such as "session" and "user" are treated
     # specially.
     # Upon completion, zero or more of the following may occur:
     #   Variables and values are set in the appropriate slave
     #   interpreter.
     #   The user is defined in the state array.
     #   The session is destroyed.

     foreach {name value} $query {
         if {[string match "user" $name]} {
             set user [string trim $value]
             if {[string match $user ""]} {
                 Session_Destroy $session
                 return 3
             } elseif {![info exist state(user)]} {
                 if {[Fmkt_UserLock $user]} {
                     Session_Destroy $session
                     return 2
                 } else {
                     set state(user) $user
                     interp eval $interp [list set user $user]
                 }
             }
         } elseif {[string match "cancel" $name] &amp;&amp; $value} {
             Session_Destroy $session
             return 0
         } elseif {[string match "save" $name] &amp;&amp; $value} {
             if {[Fmkt_DbSave $session $query]} {
                 Session_Destroy $session
                 return 4
             } else {
                 return 1
             }
         } else {
             # Define variables in the slave interpreter so they are =
there before
             # we do a Doc_Subst on the page!
             interp eval $interp [list set $name $value]
         }
     }
     return 1
 }

 proc Fmkt_ErrorPage {sock error} {
     global Fmkt
     upvar #0 Httpd$sock data
         append result "&lt;META HTTP-EQUIV=3D\"REFRESH\" =
CONTENT=3D\"3;URL=3D$Fmkt(startpage)\"&gt;"
         append result $error&lt;BR&gt;&lt;P&gt;
         append result " This page will redirect to the &lt;A =
HREF=3D$Fmkt(startpage)&gt;start page&lt;/A&gt;"
         Httpd_ReturnData $sock text/html $result
 }

 # Set the Formkit tag and view for the open datafile.
 proc Fmkt_DbView {session db view} {
     upvar #0 Session:$session state
     set state(db) $db
     set state(view) $view
     return ""
 }

 # Check that the row or record is not being edited
 # by another session.

 proc Fmkt_UserLock {user} {
     foreach id [info globals Session:*] {
       upvar #0 $id session
       if {[info exist session(user)]} {
           if {[string match $session(user) $user]} {
                return 1
           }
       }
     }
     return 0
 }

 # Retrieve row based on unique "user" and drop values
 # in the session's slave interpreter

 proc Fmkt_DbLookup {session} {
     upvar #0 Session:$session state
     set interp $state(interp)
     if {[info exists state(errorpass)]} {
         return
     } else {
         set position [mk::select $state(db).$state(view) -exact user =
$state(user)]
         if {[string match "" $position]} {
             foreach name [mk::view info $state(db).$state(view)] {
                if {[string match "user" $name]} {
                    continue
                } else {
                    interp eval $interp [list set $name ""]
                }
             }
         } else {
             set state(pass) [mk::get $state(db).$state(view)!$position =
pass]
             foreach {name value} [mk::get =
$state(db).$state(view)!$position] {
                     interp eval $interp [list set $name $value]
             }
         }
     unset position
     interp eval $interp [list set newpass ""]
     interp eval $interp [list set vfypass ""]
     }
 }

 # Collect all the return values and check if password and verify =
password
 # match. Crypt the password then write the values back to the database.

 proc Fmkt_DbSave {session query} {
     upvar #0 Session:$session state
     set interp $state(interp)
     lappend field_values user $state(user)

     foreach {name value} $query {
              if {[string match "session" $name]} {
                  continue
              } elseif {[string match "save" $name]} {
                  continue
              } elseif {[string match "newpass" $name]} {
                  set $name $value
                  interp eval $interp [list set $name $value]
              } elseif {[string match "vfypass" $name]} {
                  set $name $value
                  interp eval $interp [list set $name $value]
              } else {
                set $name $value
                lappend field_values $name $value
                interp eval $interp [list set $name $value]
              }
     }
     set newpass [string trim $newpass]
     set vfypass [string trim $vfypass]
     if {![info exists state(pass)]} {
         if {[string match $newpass ""]} {
              set state(errorpass) "Must enter a password!"
              return 0
            }
     }
     if {[string compare $newpass $vfypass] !=3D 0} {
          set state(errorpass) "New and Verify Passwords do not match!"
          return 0
     }
     set position [mk::select $state(db).$state(view) -exact user =
$state(user)]
     lappend field_values pass [Fmkt_passCrypt $newpass]
     if {[string match "" $position]} {
         eval mk::row append $state(db).$state(view) $field_values
     } else {
         eval mk::set $state(db).$state(view)!$position $field_values
     }
     mk::file commit $state(db)
     unset field_values
     return 1
 }

 proc Fmkt_passCrypt {newpass} {
     set passcrypt [tclcrypt $newpass 91]
     return $passcrypt
 }

 proc Fmkt_formSession {session args} {
     upvar #0 Session:$session state

     append result "&lt;input type=3Dhidden name=3Dsession =
value=3D\"$session\"&gt;"
     return $result
 }

 proc Fmkt_errorPass {session} {
     upvar #0 Session:$session state

     if {[info exists state(errorpass)]} {
         return $state(errorpass)
     } else {
         return
     }
 }

 # Use this procedure for authentication. It is to be called from
 # a .tclaccess file in the Directory you want authenticated access too.
 # In the .tclaccess file put the following
 #     set realm "TclHttpd"
 #     set callback Fmkt_AuthChecker

 proc Fmkt_AuthChecker {sock realm user pass} {

 set row [mk::select users.details -exact user $user]
 array set userdb [mk::get users.details!$row]

 set salt [string range $userdb(pass) 0 1]
 set passcrypt [tclcrypt $pass $salt]
     if {[string compare $user $userdb(user)] =3D=3D 0 &amp;&amp;
             [string compare $passcrypt $userdb(pass)] =3D=3D 0} {
         return 1
     } else {
         return 0
     }
 }</PRE>
<H4>**************************** End fmkt.tcl =
**************************</H4>
<P><B>The following are placed in the /htdocs directory</B></P>
<H4>******** Begin start.tml ************</H4><PRE> [
 Doc_Dynamic
 ]

 &lt;!Doctype HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"&gt;
 &lt;Html&gt;
 &lt;Head&gt;
 &lt;Title&gt;Start.tml&lt;/Title&gt;
 &lt;/Head&gt;
 &lt;Body&gt;

 &lt;p&gt;
 This an example of a username/password database..
 &lt;p&gt;
 &lt;a HREF=3D"page1.fmkt?session=3Dnew"&gt;Start Session&lt;/a&gt;

 &lt;/Body&gt;
 &lt;/Html&gt;</PRE>
<H4>************** End start.tml **************</H4>
<H4>**************Begin page1.fmkt ************</H4><PRE> [
 DbView users details
 ]

 &lt;html&gt;
 &lt;head&gt;
 &lt;meta http-equiv=3D"Content-Type" content=3D"text/html; =
charset=3Dwindows-1252"&gt;
 &lt;title&gt;Page1.fmkt&lt;/title&gt;
 &lt;/head&gt;

 &lt;body&gt;
 &lt;H3&gt;Add or Edit a User&lt;/H3&gt;
 &lt;form method=3D"POST" action=3D"page2.fmkt"&gt;
 [formSession]
 &lt;p&gt;&lt;input type=3D"submit" value=3D"Add/Edit a Username" =
&gt;&lt;input type=3D"text" name=3D"user" size=3D"25"&gt;&lt;/p&gt;
 &lt;/form&gt;
 &lt;form method=3D"POST" action=3D"page1.fmkt"&gt;
 &lt;p&gt;
 &lt;input type=3D"submit" value=3D"Cancel"&gt;&lt;input type=3D"hidden" =
name=3D"cancel"&gt;
 &lt;/form&gt;
 &lt;/body&gt;
 &lt;/html&gt;</PRE>
<H4>************ End page1.fmkt **************</H4>
<H4>************ Begin page2.fmkt ************</H4><PRE> &lt;html&gt;
 &lt;head&gt;
 &lt;meta http-equiv=3D"Content-Type" content=3D"text/html; =
charset=3Dwindows-1252"&gt;
 &lt;title&gt;Page2.fmkt&lt;/title&gt;
 &lt;/head&gt;

 &lt;body&gt;
 &lt;form method=3D"POST" action=3D"page2.fmkt"&gt;

 [formSession]
 [DbLookup]
 &lt;input type=3Dhidden name=3Dsave value=3D1&gt;
 &lt;TABLE width=3D\"600\" bgcolor=3D\"#cc3300\" border=3D\"1\" =
cellpadding=3D\"3\" cellspacing=3D\"3\"&gt;
 &lt;TR&gt;
 &lt;TD&gt;Username:&lt;/TD&gt;&lt;TD&gt;$user&lt;/TD&gt;
 &lt;/TR&gt;&lt;TR&gt;
 &lt;TD&gt;Name:&lt;/TD&gt;&lt;TD&gt;&lt;INPUT type=3D\"TEXT\" =
size=3D\"25\" name=3D\"longname\" value=3D\"$longname\"&gt;&lt;/TD&gt;
 &lt;/TR&gt;&lt;TR&gt;
 &lt;TD&gt;Location:&lt;/TD&gt;&lt;TD&gt;&lt;INPUT type=3D\"TEXT\" =
size=3D\"25\" name=3D\"location\" value=3D\"$location\"&gt;&lt;/TD&gt;
 &lt;/TR&gt;&lt;TR&gt;
 &lt;TD&gt;Phone:&lt;/TD&gt;&lt;TD&gt;&lt;INPUT type=3D\"TEXT\" =
size=3D\"25\" name=3D\"phone\" value=3D\"$phone\"&gt;&lt;/TD&gt;
 &lt;/TR&gt;&lt;TR&gt;
 &lt;TD&gt;Email:&lt;/TD&gt;&lt;TD&gt;&lt;INPUT type=3D\"TEXT\" =
size=3D\"25\" name=3D\"email\" value=3D\"$email\"&gt;&lt;/TD&gt;
 &lt;/TR&gt;&lt;TR&gt;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -