PDA

View Full Version : Simple authentication mechanism



alef13
11 Jan 2008, 7:07 PM
I wrote this simple authentication mechanism using FormPanel. There are examples of login and logout scripts written in python, but it lacks session management because it's out of the scope.

I assume that apache is configured properly and python extensions such as cgi and json are already installed.

Below is the first file, index.html:


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="ext-2.0/resources/css/ext-all.css">
<style rel="stylesheet" type="text/css">
.panel-items{margin:10px;}
</style>

<script type="text/javascript" src="ext-2.0/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="ext-2.0/ext-all.js"></script>

<!-- application -->
<script type="text/javascript" src="index.js"></script>
</head>

<body style="padding:20px;"></body></html>


The next one is the javascript code that creates the login form and submit button, index.js:


Ext.onReady(function(){
var login = new Ext.FormPanel({
labelWidth:80,
frame:true,
title:'Restricted access',
width:230,
default:{autoHeight:true},
defaultType:'textfield',

items:[{
fieldLabel:'username',
name:'user',
allowBlank:false,
},{
fieldLabel:'password',
name:'pass',
inputType:'password',
allowBlank:false,
}],
buttons:[{
text:'Login',
handler:function(){
login.getForm().submit({
method:'POST',
waitTitle:'Connecting',
waitMsg:'Sending data...',
url:'/cgi-bin/login.cgi',
success:function(){
/* url must be changed to another CGI to
validade user's session */
var url = '/main.html';
window.location = url;
},
failure:function(form, action){
if(action.failureType == 'server'){
obj = Ext.util.JSON.decode(action.response.responseText);
Ext.Msg.alert('Oops!', obj.errors.reason);
}else{
Ext.Msg.alert('Oops!', 'Authentication server is unreachable');
}
login.getForm().reset();
},
});
},
}],
});

login.render(document.body);
});


It does asynchronous POST to login.cgi, that is a python script. The interesting thing here is that FormPanel's submit does a standard POST to the script but expect a specific JSON data structure as response, according to the rules of Action.submit (http://extjs.com/deploy/dev/docs/?class=Ext.form.Action.Submit).

Below is the python code of login.cgi, that replies the expected JSON data structure:


#!/usr/bin/env python

import cgi, json

def err(message):
return (json.write({'success':False, 'errors':{'reason':message}}))


def auth(u, p):
""" here you need to implement session control and real auth mechanism """
if u == 'admin' and p == '123':
print json.write({'success':True})
else:
print err('Invalid username or password')


if __name__ == '__main__':
print 'Content-type: text/x-json\n'

form = cgi.FieldStorage()
if not form.has_key('user') or not form.has_key('pass'):
print err('No way.')

auth(form['user'].value, form['pass'].value)


Once this script replies with {"success":true} JSON data structure, FormPanel's submit success method is executed. In this example it's being redirected to main.html while in real scenario it should redirect to another CGI that at least check user's session before loading content.

Anyway, the next one is main.html with the logout button:


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="ext-2.0/resources/css/ext-all.css">
<style rel="stylesheet" type="text/css">
.panel-items{margin:10px;}
</style>

<!-- GC -->
<!-- LIBS -->
<script type="text/javascript" src="ext-2.0/adapter/ext/ext-base.js"></script>
<!-- ENDLIBS -->

<script type="text/javascript" src="ext-2.0/ext-all.js"></script>

<!-- application -->
<script type="text/javascript" src="main.js"></script>
</head>

<body></body></html>


Nothing special. At least it loads main.js, as follows:


Ext.onReady(function(){
var win = new Ext.Window({
layout:'fit',
width:500,
height:200,
closable:false,

buttons:[{
text:'Logout',
handler:function(){
Ext.Ajax.request({
url:'/cgi-bin/logout.cgi',
success:function(){window.location='/index.html';},
failure:function(){window.location='/index.html';},
});
},
},{text:'Hello world!'}]
});

win.show(document.body);
});


When the logout button is clicked it does asynchronous GET to logout.cgi, that should remove user's session from the server and guarantee that such user isn't authenticated anymore.

Here's a template of logout.cgi:


#!/usr/bin/env python

def remove_session():
pass

if __name__ == '__main__':
print 'Content-type: text/x-json\n'

remove_session()


That one should do the job, but you have to write your own session management or use something like Django to do that.

Well, as I'm new to ExtJS it may not be perfect, but from my point of view it's a nice way to do user authentication. I hope it helps. ;)

vlados
14 Jan 2008, 2:46 AM
Add the enter key ;)

hpet
28 Feb 2008, 6:04 AM
I have something very much similar.

But there is one little thing that doesn't leave me alone:
Is there any way to avoid second time ext lib loading when login is successfull and page is redirected to main html? Main page includes all libs again and this may mean reloading lots of kb's.

Any thoughts on this?

djfiii
28 Feb 2008, 6:23 AM
they should be cached from the first load

hpet
28 Feb 2008, 6:41 AM
That is true.
But what if caching is disabled or whatever?
Should I just not think about it? Am I "over-optimizing"?

Even if caching does take care of this and spares a visitor another lib downloading, browser will still have to reinterpret the whole library, right? wrong?

Wouldn't it be nice if we somehow keep and reuse already interpreted library?
What if instead of redirecting to a main page, we somehow replace DOM element (i.e. body?) with our "main page body"? this way already interpreted JS libs would just re-render some DOM elements.

Let's say that on "success" we receive and handle JSON which would "extend" our already build DOM tree into our main page, or have a seperate ajax call which would return us a new body including additional custom ext scripts.

What do you think?

djfiii
28 Feb 2008, 10:34 AM
there is no reason you couldn't do that - most of the larger example apps seem to contain the login and app all in one page. Another option is to load js files on an "as-needed" basis. There are threads on that if you do a forum search. I've not spent any time on optimization, as I have enough trouble getting incremental additions to my layout working properly :)

hpet
28 Feb 2008, 11:08 PM
Yes, I have been playing with this idea.
The main reason why I would like to optimize it a bit is because my target group of users is very unpatient. Even if they get a message "Please wait..." many of them keep pressing the same thing over and over again like it will help to speed things up :)

galdaka
28 Feb 2008, 11:28 PM
Hi,

I create a more complicate autenthication class: http://extjs.com/forum/showthread.php?t=27399


Greetings,