- Hi and Welcome to -
++++++++++++++++++++++++++++++++
LASSO TIPS FOR NEWBIES: 2.9
++++++++++++++++++++++++++++++++
I'm your host, M i l e s.
First and foremost, a good place for you to start with Lasso is the
following 4 things:
The FIRST LASSO TIPS FOR NEWBIES
-> http://www.listsearch.com/lassotalk.lasso?id=143312
The LAST LASSO TIPS FOR NEWBIES
-> http://www.listsearch.com/lassotalk.lasso?id=149158
10 LASSO RESOURCES
-> http://www.listsearch.com/lassotalk.lasso?id=143018
THE LASSO RESOURCES ADDENDUM
-> http://www.listsearch.com/lassotalk.lasso?id=143417
++++++++++++++++++++++++++++++++
TODAYS TIP:
The Login Routine
++++++++++++++++++++++++++++++++
Today's tip has a lot of information in it, and if you've been
reading my posts over the last few weeks/months while Ive been on
hiatus on the Lasso list you've seen me make the same post over and
over again....the Login Routine! Because there's a lot of
information to convey in today's tip, I'll try to keep the chit-chat
short. However let me point out from the start that my solution to a
LOGIN routine is NOT everyone's solution, it just happens to be my
methodology to it. I have spent the better portion of 5 years
working out this routine, and over the last year heavily writing it
and rewriting it getting it to a point of stable functionality, which
is the goal of any good developer - get it to work, get it to work
correctly - you get paid. Now if only Doctors and Lawyers worked
that way. Its still not perfect but it does work and it works well.
My solution entails the use of SESSIONS, so if you haven't used
sessions, you will now and you'll thank me for it later. Also this
solution does not take into account being MULTIUSER aware, meaning
types of users. For that, you'd have to rewrite this logic,
completely. I know...Ive done it. With multiple login types you
will need to rewrite the better portion of the validation and session
logic. And this solution doesn't take that into consideration, but
the roots of it are there...my current solution (which you're about
to see) was actually stripped of this functionality so that you could
see the basics.
PART ONE: Login! Vee Don't Need NO Stinkin' Login!
Like hell you don't. Nearly ever data driven website on the
internet today has some kind of login routine that it requires in
order to garner from the user who they are, what their user
preferences are (or could be), and then redirect that user to their
specific record or series of records that pertain to them and them
alone. Because you don't want an end user to see anyone else's data,
you want them to see ONLY their information...you have to provide
some level of security, or at least make it appear as such. Let me
say from the outset that this solution is database independent.
Meaning you can use FileMaker for this, if you want, however you'd be
better off with a SQL solution across the board for a variety of
reasons, not the least of which is (separately) speed and security.
The things you'll need are essentially 3 pages, which can be
combined into 1 but for the purposes of this LassoTip we're going to
put them into their separate pages. I will comment out and explain
where necessary, but is assumed here that you have a basic
understanding of FORMS and their function.
The Login Form. The form itself (below) is really just a basic
form. It consists of TWO fields, a username and password field.
Note that the form name/value pairs are NOT being processed by the
form, or by a lasso cgi (that's the ACTION statement), and also note
that the submit statement is a NOTHING subtag. You should get into
the habit of using the -NOTHING tag for all form submissions. It
allows you greater flexibility on the receiving side of the form to
do what you want to do with the data.
<form action="login-validate.lasso" method="POST">
<table cellpadding=3 cellspacing=0 border=0>
<tr bgcolor="#EEEEEE">
<td align="right">username:</td>
<td align="left"><input type="TEXT" size="20"
name="user"></td>
</tr>
<tr bgcolor="#CCCCCC">
<td align="right">password:</td>
<td align="left"><input type="PASSWORD" CLASS="TEXTBOX"
size="20" name="pass"></td>
</tr>
<tr><td colspan="4"> </td></tr>
<tr><td colspan="2" align="center"><input type="SUBMIT"
name="-NOTHING" value="login"></td></tr>
</table>
</form>
In the form above, I've made the name/value pairs very simple
for purposes of easy reading, however, ideally what you want to do,
is change the names of the name fields to be something innocuous.
And the reason being is that as FMP developers or new developers
you'll have a want to send the name of the actual field that you're
searching on. That's a no-no, a security risk. Never ever do that.
So ideally if this were the real world, you might want to do the
following to your field names:
<td align="left"><input type="TEXT" size="20" name="e1"></td>
As you can see, the name side of the name/value pair has been
anomynized. You could use this form for anything. Its only on the
receiving side of things where the actual values of the form will get
played with so you're not locked into anything here...it just gives
you LOTS of freedom to play with data. Also note one other thing
here, that the password field is denoted as a password and NOT a text
field. While this is strictly an end user thing, the password while
appearing as dots will be sent in clear text, UNLESS the site is
using an SSL certificate. This tip does not deal with SSL
certificates but it should be noted that ANY form values sent via the
internet unless otherwise encrypted will be sent in clear text. That
means in layman's terms, that if you're sniffing the TCP stream from
another computer on the network, you will literally see the form
values being sent to the server in the TCP stream unencoded.
PART TWO: Validation and Starting a Session.
For the validation page, as I like to refer to it, I like to run
the whole thing as a LassoScript, you can run it as Lasso Square
Bracket but LassoScript has one advantage over LSB, and that is that
is doesn't take up space in a browser, meaning there are no carridge
returns to report back to the browser. No output to the browser at
all. I find it easier to read than LSB code but that's a personal
preference.
<?LassoScript.
include: 'insert-dbvalues.inc';
// SECTION 1
var: 'e1' = (action_param: 'e1'), // set username
'e2' = (action_param: 'e2'); // set password
//note: ALWAYS ALWAYS ALWAYS convert your action_parameters to
variables!
// SECTION 2
inline: ($db_connection), -op='eq', 'u_name'=($e1), -op='eq',
'p_word'=($e2), -search;
protect; // this is here in case there's an
error, we don't want
// an error showing to the user.
// SECTION 3
if: (found_count) == 1; // if there's an exact match
begin session and redirect to datapage
session_start: -name='ACCESS', -expires='30', -uselink;
session_addvar: -name='ACCESS', 'v_username';
session_addvar: -name='ACCESS', 'v_date';
session_addvar: -name='ACCESS', 'v_time';
var: 'v_username' = ($e1),
'v_date' = ((Date_Format:
(Date_GetCurrentDate), -DateFormat='%Y-%m-%d'),
'v_date' = ((Date_Format:
(Date_GetCurrentDate), -DateFormat='%H:%M');
redirect_url:'userpage.lasso?&-session=ACCESS:' +
(Session_ID:-name='ACCESS');
else; // this is where we redirect the end user back
to login for failure.
redirect_url:'login.lasso';
/if;
/protect;
/inline;
?>
The script above is rather straight forward, however let's go
through this section by section.
SECTION 1. This section deals with converting the two form
parameters, the VALUES or left side of the Name/Value pair into
variables so that we can use them. While this practice of converting
ones action parameters into variables is a good practice to get into
for several reasons, not the least of which is the fact that
action_parameters can be LOST once acted upon. Variables can not.
Or more to the point, they can't be changed, or reused inside an inline.
SECTION 2. This section deals with 2 things primarily. The
first is the inline that will do the actual search against the db,
and the second is the protection of the results, which we'll get to
in a bit.
Firstly take a gander at the inline. Note that it doesn't look
like your normal inline, primarily because its missing somethings,
like database names, table names, and keyfield values. That's
because, and this is again a personal preference as well as
convention of the day in the lasso world in general, that to give you
greater flexibility with your inlines, you create database connection
variables. These are variable arrays that allow you to literally
anonymize your datasources, making your logic somewhat independent of
the datasources being used. Why do this ? Flexibility. Your
databases may change over time....and rather than hardcode the
database and tables throughout your applications, you put those
values into an array, and then call the array as a variable.
The second thing about this inline is that it is doing an
explicit search for EXACT values against the table in question. When
you do an EXACT match its matching from LEFT TO RIGHT exactly as it
appears in the field. If there's a stray character feed at the end
of the form value for username (for instance) and you go to look for
against the database, Lasso will return a NULL match, so its a good
idea to STRIP your variables and form values of any stray characters
that may get caught in the datastream. However for the purposes of
this example we don't use this instance here. So to invoke an EXACT
match against the fields in question, you use -OP='EQ'. This means
in layman's speak, USE THE OPERATOR 'EQUALS' AGAINST FOLLOWING FIELD
ONLY, SEEKING THIS EXACT VALUE ONLY. Hmmm wow, all that contained in
8 chrs. Note that there are two of these operators. One for each
field. If those operators weren't there, Lasso would pull back a
multitude of potential responses that may match what you were after.
By default Lasso performs a begins with (or -op='bw') search from
left to right, that means if you search for '11234' against a series
of records that contains '11245', '12345', '01134', and '23456', it
will pull back '11245', '12345', as valid responses. So if you don't
tell it to perform an explicit search against the fields in question
it will search from left to right finding all sorts of potential
matches!
Protection. This line, literally protects the code that's
contained within the enwrapped code from displaying to the end user
an kind of error in any way, shape or form. This is more for your
app to look pretty so that you don't see an ISE or the dreaded Lasso
Blue Banded Error Screen, and your clients don't think you're an
idiot who couldn't code your way out of a wet paper bag.
SECTION 3. This section deals with a successful finding of ONE
SINGULAR record, and the creation of a session and its variables, as
well as its opposite, the NOT finding of a one singular record that
matches the exact parameters of the search in question.
Two things of note here is starting the session itself, note Im
using LINKS instead of cookies. As with sessions you have the option
to use both, I prefer not to expend the processing power that way,
just use links. Much safer that way. Secondly is setting a
timelimit to the session itself. By default sessions are implimented
for 20 minutes, however, I find that that's not long enough for most
uses. 30 is better. YMMV.
Setting the session is easy, so how do you populate it ? I have
one request that I'd like to see in how sessions are implemented in
the next version of Lasso and that's to directly TIE a session
variable to a value like session var = "some value". However that's
not how this game gets played. Nope. You'd think that's how it
works but it doesn't. Note after I set the session variables, I also
create and populate 3 variables. The 3 variables also happen to have
the same name as my session variables. So NOW those session
variables are populated. Yipppee. Confused the hell out of me first
couple of times I used sessions. OP ? Listening ? SESSION VARIABLE
= SOME VALUE! Drives me nuts. Ok, done with my soap box.
Once all you've got your session variable set and populated, you
direct the end user to their specific datapage. And that's exactly
what I do.
If the end user IS NOT FOUND or there isn't an exact match then
we redirect to the login page.
But first....a word from our sponsors...
PART THREE: THREE LICKS.
So just how many licks does it take to get to the center of a
tootsie roll pop ? Let's find out. ONE, TWO....THREE! <-CRUNCH->
Yes! Three! And that my friends brings us to PAGE 3 of our lil toy
the actual userpage.lasso. In short once you've got your user to
their data page, this is the simple part, and all you need do is
check to see if their session is a valid one, and keep doing that.
What follows is the entire logic of userpage.lasso and any page, in
actuality, where you're needing to force a login under any
condition. What this logic does is ask the all important question,
are you a valid session ? IF you are, great here's the data
associated with that session, if you're not BAM! you get booted:
[include: 'insert-dbvalues.inc']
[include: 'sessioncheck.inc']
[if: ($v_sessioncheck) != 'EXPIRE']
<!-- DISPLAY PAGE INFO -->
[else]
<!-- REDIRECT USER -->
[/if]
The real magic of the userpage.lasso sits in sessioncheck.inc.
<?LassoScript
1.) session_start: -name='ACCESS', -expires='30', -uselink;
2.) session_addvar: -name='ACCESS', 'v_username', 'v_date',
'v_time';
3.) var: 'v_sessioncheck' = (session_result);
?>
That's it. That's all.
Let's go through this line by line....
1.) I start the session named 'ACCESS'.
"Wait. Ummmmm Mister Miles...didn't you already start the
session on the login-validate.lasso page ?"
Why yes I did. And now we have to start it again. You see
because the web is a stateless place we have to have some way of
keeping state and that's exactly what we're doing. In short, we're
identifying THIS page with the state we already created. Yes I know
its a bit confusing, because you're starting the session again. I
know that. However, listen to your old pal Miles here. You're
starting it again. HOWEVER that's a misnomer. What you're actually
doing is CHECKING the session here. Lasso knows its you. The
language just doesn't allow a more intuitive mechanism. (OP ? You
listening, again ? Helpful hint for LP9 - Session Language needs a
tweak. ) That said....all you're doing is checking the session here,
that's it. How does it relate back to you or know that that session
is the right session? Look at the URL that's been generated, note
the session ID value? That's how it knows. This value will pass
from page to page, or propagate automatically from page to page, as
long as you start the session at the top of every page that you need
to carry session variables.
2.) We're calling the session variables, again this is a
misnomer. Because the first time we did this, it was literally
adding those values. Now we're not adding values, we're calling
them. They already have values. We can change them if we want by
setting variables with the same names further down on the page, and
the next time we call them, they'll have NEW values. However all
we're doing is calling them, and once we've done so, they're now
available to the page that we're on.
3.) SESSION_RESULT. This lil toy saved me HOURS of coding, and
I mean HOURS of coding. Session_Result has THREE possible values:
NEW, LOAD, or EXPIRE. In this instance, the session "ACCESS" is in
LOAD condition, and it will continue to be in LOAD condition as long
as we're active. (IE: we keep clicking links) However the clock is
ticking, if we step away from our computer for up to 29 minutes & 59
seconds, the session is still active and all we need do is click on
any link which will reset the session clock back to 30. However, if
we reach the 30 minute mark, the session goes stale and BAM! Our
session_result is now equal to EXPIRE and that may friends is what
v_sessioncheck is all about... I set a variable for session_result
to equal v_sessioncheck no matter what it is.
Let's look at our page logic again...
[include: 'insert-dbvalues.inc']
[include: 'sessioncheck.inc']
[if: ($v_sessioncheck) != 'EXPIRE']
<!-- DISPLAY PAGE INFO RELATED TO USER -->
[else]
<!-- REDIRECT USER -->
[/if]
And we note that $v_sessioncheck is checking to see if the value is
NOT expire. If its either NEW or LOAD, run the page contents inside
the IF statement...else boot them to the login page.
CONCLUSION:
This is just a small example script and bit of logic that can
'simulate' a login experience. I say simulate because they're not
actually logging into anything, lasso is basically checking them
against a series of values in the database (username/password), and
then allowing them to see records related to them from there.
Remember its a simulation. If this were an actual database...yadda
yadda yadda. Just kidding. In short, this is one of many ways to
accomplish the concept of a login. YMMV. Play around with it.
Please. If you discover a better way, please by all means share with
the group.
Three things to point out here:
1.) This solution does not have anything in any way, shape or
form to do anything with Lasso Security. It does not replace it, it
does not remove it....it does however if you've read my methodology
on db_connection array variables use lasso security in that respect.
2.) This solution can be defeated (to a degree), and if you can
tell me how and why, offlist, AND your the first person that gets it
right, I'll send you a box of your favorite chocolate. However, the
solution must be sent to me privately. If its submitted publicly I
will not accept it as a valid response. I will post the results of
how and why, and how to build a better mousetrap in a later LTÆ’N/F.
IF no one gets it, that's alright...I still have to show you how to
build a better mouse trap and trust me there is a better mouse trap!
3.) The Better Mouse Trap ? Requires a LOT programming, not to
mention an SSL certificate, AND Two Sessions with longer IDS. And
that's just for starters. Which should give you a hint as to how to
defeat this mouse trap.
LAST WORDS:
In future as LASSO TIPS moves forwards, I would ask that if someone
has a comment about a tip, please change the subject line
accordingly....its a request people, not a demand.
That said...Happy Lassoing.
M i l e s.
––– LASSO EVANGELIST FOR HIRE: GREAT RATES –– NEEDS WORK –––
-don't know what lasso is ? - http://www.omnipilot.com/
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
M i l e s miles@lassoevangelist.com
MagicMiles Software (415) 686 - 6164
http://www.lassoevangelist.com/ AIM/Yahoo/MSN: magikmiles
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
Creating custom content management systems for yoga, dance,
healing arts, & now real estate starting at just $65.00 a
month, incld: domain registration, web hosting, email and
webmail, and access to TOOLBOXENGINE! A very robust tool.
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
--
------------------------------
Lasso Support: http://support.omnipilot.com/
Search the list archives:
http://www.listsearch.com/lassostudiotalk.lasso
Manage your list subscription:
http://www.listsearch.com/lassostudiotalk.lasso?manage