ajax-login-system 学习笔记

ajax-login-system  是google上一个开源的利用ajax技术的用户登陆系统

http://code.google.com/p/ajax-login-system/

通过学习这个系统,可以了解如何构建基于webservice的ajax应用(即以服务器端为中心的ajax应用).

登陆控件客户端主要有如下文件

Skin-LoginStatusControl.ascx  Html代码及一些加载其他文件的代码
Skin-LoginStatusControl.css    样式表文件
Skin-LoginStatusControl.js
SnipControls.js               登陆注册控件相关的js代码

先来开SnipControls.js文件

  1//------------------------------------
  2// Implementation of:
  3//  - Snip namepace
  4//  - Snip.LoginControl class
  5//  - Snip.RegisterControl class
  6//
  7// BSD License: http://www.opensource.org/licenses/bsd-license.php
  8//Copyright (c) 2007, Kyle Beyer (http://daptivate.com)
  9//All rights reserved.
 10//
 11//Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 12//
 13//Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 
 14//Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 
 15//Neither the name of the organization nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 
 16//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 17//------------------------------------
 18 
 19//
 20// Namespace
 21var Snip = (function(){
 22    //
 23    // private namespace members
 24    var _debug = 1;    
 25    //
 26    // password length (private)
 27    var _pLength = 6;
 28    //
 29    // status control //状态控件
 30    var _status = null;             
 31    //
 32    // username
 33    var _username = '';    
 34    //
 35    // authentication status
 36    var _auth = false;
 37    //
 38    // persist cookie flag
 39    var _persistCookie = false;
 40    
 41    //
 42    // private namespace functions
 43    
 44    //
 45    // helper function to clear a control's value and give back focus
 46    function ClearControl(ctrl, giveFocus){
 47        ctrl.value = '';
 48        if( giveFocus ){ ctrl.focus(); }
 49    }

 50      
 51    //
 52    // username validation
 53    function CheckUsername(u){
 54        var filter  = /^[0-9a-zA-Z_\.\-\s]+$/;
 55        return filter.test(u);
 56    }

 57          
 58    //
 59    // e-mail validation
 60    function CheckMail(e){
 61        var filter  = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
 62        return filter.test(e);
 63    }

 64    
 65    //
 66    // common timeout method
 67    function OnTimeout(result){
 68        SetStatus("Sorry, the request was taking too long.  Please try again.""bad");
 69    }

 70        
 71    //
 72    // common error method
 73    function OnError(result){        
 74        var resultMessage = result.get_message();
 75        var errorMessage = "Exception: " + resultMessage;    
 76        errorMessage = errorMessage + "\n-----------------------------------\n";
 77        errorMessage = errorMessage + " StackTrace: + ";
 78        errorMessage = errorMessage + result.get_stackTrace();
 79       
 80        if( _debug == 1 ){
 81            alert(errorMessage); 
 82        }
   
 83        SetStatus("Error: " + resultMessage + ".""bad");
 84    }

 85    
 86    //
 87    // called when status needs displayed  当状态需要显示时调用
 88    function SetStatus(m, t){
 89        _status.style.display = "block";
 90        _status.innerHTML = m;
 91        
 92        if( t == "bad" ){
 93            _status.className = 'form-status bad';  //主要是bad起作用
 94        }
else if( t == "good" ){
 95            _status.className = 'form-status good';                
 96        }
else{
 97            _status.className = 'form-status ok';               
 98        }

 99    }

100    //
101    // called when status needs cleared   清除状态控件内容
102    function ClearStatus(){
103        _status.innerHTML = '';
104        _status.style.display = "none";
105    }

106    
107    return {             
108        //
109        // LoginControl javascript object   LoginControl类
110        //
111        LoginControl : function(eID, pID, sID, cID, aID, uID){
112        //'UserName-L', 'Password-L', 'Status-L', 'login_control', 'server-auth-status', 'server-username'
113    // 电子邮件    密码   状态    控件    验证    用户名 
114            //
115            // declare request objects (private)
116            var _saltRequest = null;
117            var _loginRequest = null;
118            //
119            // declare form control names/ids
120            var _eID = eID;
121            var _pID = pID;
122            var _sID = sID;            
123            var _cID = cID; 
124            var _aID = aID;           
125            var _uID = uID;           
126            //
127            // declare document control vars (public)
128            var _e = null;
129            var _p = null;
130            var _c = null;            
131            //
132            // set status control
133            _status = null;            
134            //
135            // open status
136            var _open = false;            
137            //
138            // login callbacks
139            var _loginCallback = null;
140            var _logoutCallback = null;     
141           
142            // --------------------------------------------
143            // PUBLIC LoginControl Functions            
144            // --------------------------------------------
145                     
146            //
147            // used to initialize authentication status from 
148            // optional hidden field (aID) populated by server  
149            // and username field (uID) pupulated by server  
150        //  初始化 认证 状态     -aID 是隐藏控件  server-auth-status   
151            this.init_fields = function(){
152                // get server auth status
153                var aF = document.getElementById(_aID);
154                if( aF != null ){
155                    var val = aF.value;
156                    if( val != null && val.length > 0 ){
157                        _auth = val=='True'?true:false;
158                    }

159                }

160                // get server username    -uID 是隐藏控件  server-username 
161                var uF = document.getElementById(_uID);
162                if( uF != null ){
163                    var val = uF.value;
164                    if( val != null && val.length > 0 ){
165                        _username = val;
166                    }
else{
167                        _auth = false;
168                    }

169                }

170            }

171            
172            //
173            // used to get authenication status  返回认证结果
174            this.get_auth = function(){
175                return _auth;
176            }
;            
177            // 
178            // used to get authenicated username   返回用户名
179            this.get_username = function(){
180                return _username;
181            }
;            
182            //
183            // used to set login callback function    设置登陆回调函数
184            this.set_loginCallback = function(value){
185                _loginCallback = value;
186            }
;
187            //
188            // used to set logout callback function   设置登陆回调函数
189            this.set_logoutCallback = function(value){
190                _logoutCallback = value;
191            }
;
192            //
193            // used to get open status     取得   open状态
194            this.IsOpen = function(){
195                return _open;
196            }
;
197            
198            //
199            // used to set pwd length   设置密码长度 
200            this.PLength = function(n){
201                _pLength = n;
202            }
;
203            
204            //
205            // called when login button is pressed   //当登陆按钮被点击时调用
206            // if 'remember me' is checked then true should be passed in.
207            this.LoginUser = function(remember){
208                // email validation   验证邮件地址 
209                var e = _e.value; 
210                if( e == null || e == ''){
211                    SetStatus("You must enter an Email.""bad");
212                    ClearControl(_e, true);
213                    return;
214                }

215                if!CheckMail(e) ){
216                    SetStatus("Invalid Email.""bad");
217                    _e.focus();        
218                    return;
219                }

220                
221                // password validation   密码客户端验证
222                var p1 = _p.value; 
223                if( p1 == null || p1 == ''){
224                    SetStatus("You must enter a password.""bad");
225                    ClearControl(_p, true);
226                    return;
227                }

228                if( p1.length < _pLength ){
229                    SetStatus("Your password must be more than " + _pLength + " characters.""bad");
230                    ClearControl(_p, true);        
231                    return;
232                }
  
233                // save persist flag
234                _persistCookie = remember;
235                
236                SetStatus("Verifying information");
237                VerifyUserName(_e.value);
238            }
;
239            
240            //
241            // called when logout button is pressed  当“登出"按钮被按下时调用
242            this.LogoutUser = function(){                
243                if( _auth ){
244                    snip.AuthenticationService.Logout(
245                                            OnLogoutComplete,
246                                            OnTimeout,
247                                            OnError);          
248                }

249            }
;
250            
251            //
252            // opens the control   //打开DIV 窗口
253            this.Open = function(){
254                // show form
255                _c = document.getElementById(_cID);   //_c 表示 div控件
256                _c.style.display = "block";                
257                
258                // get references to controls
259                _e = document.getElementById(_eID);   // _eID  代表  电子邮件文本框
260                _p = document.getElementById(_pID);   //  _pID  代表  密码 文本框
261                _status = document.getElementById(_sID);  //_sID 代表 状态 文本框
262                
263                // clear fields & set focus
264                ClearControl(_p, false);
265                ClearControl(_e, true);
266                
267                _open = true;
268            }
;
269            
270            //
271            // closes the control   //关闭Div窗口
272        
273            this.Close = function(){
274                if( _open ){
275                    // clear fields
276                    ClearControl(_p, false);
277                    ClearControl(_e, true);
278                    ClearStatus();
279                    // hide
280                    _c.style.display = "none";
281                }
    
282                _open = false;
283            }
;
284            
285            //
286            // performs event for a key press
287            this.KeyPressed = function(evt, target){                
288                if (evt && evt.keyCode == 13 && !(evt.srcElement && (evt.srcElement.tagName.toLowerCase() == "textarea"))) {
289                    var defaultButton = document.getElementById(target);
290
291                    if (defaultButton && typeof(defaultButton.click) != "undefined"{
292                        defaultButton.click();
293                        evt.cancelBubble = true;
294                        if (evt.stopPropagation){ evt.stopPropagation(); }
295                        return false;
296                    }

297                }

298                return true;
299            }
;
300            
301            // --------------------------------------------
302            // PRIVATE LoginControl Functions            
303            // --------------------------------------------
304            
305            //
306            // verifies username against membership store   
307            function VerifyUserName(u){     //验证 电子邮件  涉及到snip.SaltRequest()方法
308                _saltRequest = new snip.SaltRequest();      //SaltRequest()  这是调用服务器端的方法
309                _saltRequest.username = u;
310                
311                snip.AuthenticationService.VerifyUserLogin(_saltRequest,    //snip.AuthenticationService.VerifyUserLogin方法   这是调用服务器端的方法
312                                                            OnVerifyComplete,
313                                                            OnTimeout,
314                                                            OnError);    
315            }

316            
317            //
318            // called when username verification completes  //当电子邮件验证完成
319            function OnVerifyComplete(result){
320                if(result.success){
321                    CompleteLogin(result.salt, result.challenge);
322                }
else{
323                    SetStatus("Sorry, " + _e.value + " is not a registered email.  Would you like to <a href='#join' onclick=\"_loginControl.Close(); _registerControl.Open();\">Join</a>?""bad");
324                    ClearControl(_e, true);
325                }

326            }

327
328            //
329            // called after email is verified   邮件验证完成后调用  验证密码
330            function CompleteLogin(s, c){
331                SetStatus("Checking Password");               
332                
333                _loginRequest = new snip.LoginRequest();    //调用服务器端的方法
334                _loginRequest.username = _e.value;
335                var pwd_hmac = b64_hmac_sha1(s, _p.value);
336                _loginRequest.passwordHMAC = b64_hmac_sha1(c, pwd_hmac).toString();
337                _loginRequest.createCookie = _persistCookie;  
338                
339                snip.AuthenticationService.Login(_loginRequest,    //调用服务器端的方法
340                                                OnLoginComplete,
341                                                OnTimeout,
342                                                OnError);
343            }

344            
345            //
346            // called when authentication check completes  //当密码验证完成后
347            function OnLoginComplete(result){
348                if( result.status ){
349                    _auth = true;
350                    _username = result.username;
351                    if( _loginCallback != null && typeof(_loginCallback) == 'function' ){
352                        _loginCallback();
353                    }
else{
354                        SetStatus("Welcome, " + _username + ".""good");
355                    }

356                }

357                else{
358                    _auth = false;
359                    SetStatus("Invalid password. Please try again.""bad");
360                    ClearControl(_p, true);
361                }
 
362            }

363            
364            //
365            // called when logout request completes
366            function OnLogoutComplete(result){
367                _auth = false;
368                _username = '';
369                if( _logoutCallback != null && typeof(_logoutCallback) == 'function' ){
370                    _logoutCallback();
371                }
else{
372                    SetStatus("Successfully signed out.""good");
373                }

374            }

375            
376        }
// end LoginControl
377        
378        
379        //
380        // RegisterControl javascript object    RegisterControl类
381        //
382        RegisterControl : function(uID, eID, p1ID, p2ID, sID, cID){
383        
384            //
385            // declare request objects (private)
386            var _registerRequest = null;
387            var _checkRegistrationRequest = null;
388            //
389            // declare document control vars (public)
390            var _uID = uID;   // username control ID
391            var _eID = eID;   // email control ID
392            var _p1ID = p1ID; // password 1 control ID
393            var _p2ID = p2ID; // password 2 control ID
394            var _cID = cID; // RegisterControl content wrapper ID
395            var _sID = sID; // RegisterControl content wrapper ID
396            //
397            // declare document control vars (public)
398            var _u = null;   // username control
399            var _e = null;   // email control
400            var _p1 = null// password 1 control
401            var _p2 = null// password 2 control
402            var _c = null// RegisterControl content wrapper                        
403            //
404            // set status control
405            _status = null;            
406            //
407            // called when registration is complete
408            var _registerCallback = null;            
409            //
410            // open status
411            var _open = false;
412            
413            // --------------------------------------------
414            // PUBLIC RegisterControl Functions            
415            // --------------------------------------------
416                    
417            //
418            // used to set login callback function
419            this.set_registerCallback = function(value){
420                _registerCallback = value;
421            }
;
422            //
423            // used to set password length
424            this.PLength = function(value){
425                _pLength = value;
426            }
;
427            
428            //
429            // called when register button is pressed
430            // if 'remember me' is checked then true should be passed in.
431            this.RegisterUser = function(remember){  
432            
433                // email validation
434                var e = _e.value; 
435                if( e == null || e == ''){
436                    SetStatus("You must enter an Email.""bad");
437                    ClearControl(_e, true);
438                    return;
439                }

440                if!CheckMail(e) ){
441                    SetStatus("Invalid Email.""bad");
442                    _e.focus();        
443                    return;
444                }
 
445                
446                // username validation
447                var u = _u.value; 
448                if( u == null || u == ''){
449                    SetStatus("You must enter a Screen Name.""bad");
450                    ClearUsername(true);
451                    return;
452                }

453                if!CheckUsername(u) ){
454                    SetStatus("Your Screen Name has invalid characters.""bad");
455                    _u.focus();        
456                    return;
457                }
    
458                
459                // password validation
460                var p1 = _p1.value;    
461                var p2 = _p2.value;  
462                if( p1 != p2){
463                    SetStatus("Please re-enter your passwords.  They don't match.""bad");
464                    ClearControl(_p1, true);
465                    ClearControl(_p2, false);
466                    return;
467                }
    
468                if( p1 == null || p1 == ''){
469                    SetStatus("You must enter a password.");
470                    ClearControl(_p1, true);
471                    ClearControl(_p2, false);
472                    return;
473                }

474                if( p1.length < _pLength ){
475                    SetStatus("Your password must be more than " + _pLength + " characters.""bad");
476                    ClearControl(_p1, true);
477                    ClearControl(_p2, false);   
478                    return;
479                }
  
480                
481                // save persist flag
482                _persistCookie = remember;
483                
484                // step 1 in registration
485                SetStatus("Checking information");
486                AttemptRegistration(u, e);
487            }
;
488                        
489            this.Open = function(){
490                // show form
491                _c = document.getElementById(_cID);
492                _c.style.display = "block";                
493                
494                // get references to controls
495                _u = document.getElementById(_uID);
496                _e = document.getElementById(_eID);
497                _p1 = document.getElementById(_p1ID);
498                _p2 = document.getElementById(_p2ID);
499                _status = document.getElementById(_sID);
500                
501                // clear fields & set focus
502                ClearControl(_p1, false);
503                ClearControl(_p2, false);
504                ClearControl(_e, true);
505                ClearControl(_u, false);
506                
507                _open = true;
508            }
;
509            
510            this.Close = function(){
511                if( _open ){
512                    // clear fields                
513                    ClearControl(_p1, false);
514                    ClearControl(_p2, false);
515                    ClearControl(_e, true);
516                    ClearControl(_u, false);
517                    ClearStatus();
518                    // hide
519                    _c.style.display = "none";
520                }

521                
522                _open = false;
523            }
;
524            
525            //
526            // performs event for a key press
527            this.KeyPressed = function(evt, target){                
528                if (evt && evt.keyCode == 13 && !(evt.srcElement && (evt.srcElement.tagName.toLowerCase() == "textarea"))) {
529                    var defaultButton = document.getElementById(target);
530
531                    if (defaultButton && typeof(defaultButton.click) != "undefined"{
532                        defaultButton.click();
533                        evt.cancelBubble = true;
534                        if (evt.stopPropagation){ evt.stopPropagation(); }
535                        return false;
536                    }

537                }

538                return true;
539            }
;
540            
541            // --------------------------------------------
542            // PRIVATE RegisterControl Functions            
543            // --------------------------------------------
544            
545            
546            //
547            // called when user check returns
548            function OnCheckRegistrationComplete(result){    
549                if(!result.email_available)
550                {                 
551                    SetStatus("Email already taken.  Please use a different one or <a href=\"#sign-in\" onclick=\"_registerControl.Close(); _loginControl.Open();\">Sign In</a>.""bad");
552                    ClearControl(_e, true);
553                    return;
554                }

555                
556                if(!result.username_available)
557                {                 
558                    SetStatus("Screen Name already taken.  Please use a different one or <a href=\"#sign-in\" onclick=\"_registerControl.Close(); _loginControl.Open();\">Sign In</a>.""bad");
559                    ClearControl(_u, true);
560                    return;
561                }

562              
563                // create registration request
564                _registerRequest = new snip.RegistrationRequest();  //调用服务器端的方法
565                _registerRequest.email = _e.value;
566                _registerRequest.username = _u.value;
567                var p = _p1.value;
568                _registerRequest.pwd = b64_hmac_sha1( result.salt, p );
569                _registerRequest.salt = result.salt;
570                _registerRequest.createCookie = _persistCookie;  
571                
572                SetStatus("Creating account");
573                
574                // request user registration
575                snip.AuthenticationService.RegisterUser(_registerRequest,
576                                                        OnRegistrationComplete,
577                                                        OnTimeout,
578                                                        OnError);  
579            }

580
581            //
582            // called when registration call returns   注册完成
583            function OnRegistrationComplete(result){
584                if(result.success){
585                    // set authenticated
586                    _auth = true;
587                    _username = _u.value;
588                    // set status message
589                    var s = "Account successfully created.";
590                    if( result.email_sent ){
591                        s += "&nbsp;&nbsp;A notification e-mail was sent to you.";            
592                    }

593                    s += "&nbsp;&nbsp;<a href='#' onclick='_registerControl.Close();'>OK</a>";
594                    SetStatus(s, "good");
595                    // callback
596                    if( _registerCallback != null && typeof(_registerCallback) == 'function' ){
597                        _registerCallback();
598                    }

599                }

600                else{
601                    SetStatus("Account creation failed: " + result.message + ".""bad");
602                }
 
603            }

604
605            // 
606            // called when client-validation is complete   当客户端验证完成后调用
607            function AttemptRegistration(u, e){
608                _checkRegistrationRequest = new snip.CheckRegistrationRequest(); 
609                _checkRegistrationRequest.email = e;
610                _checkRegistrationRequest.username = u;
611                // first step: check if user exists           
612                snip.AuthenticationService.CheckRegistration(_checkRegistrationRequest,
613                                                             OnCheckRegistrationComplete,
614                                                             OnTimeout,
615                                                             OnError);
616            }

617            
618        }
 // end RegisterControl
619
620    }
 // end return
621
622}
)(); // end Snip
623
624// notify atlas script has loaded
625if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();


posted on 2008-01-05 16:20  蓝蓝的天2016  阅读(1722)  评论(0)    收藏  举报