Jon,

> Thanks for the replies.

     No sweat.  This seems to be one of the first speed bumps folks
run into. Lately I've been thinking a lot about putting together a
tutorial on how webservers and browsers work, for servlet developers.

> My actual form tag looks like this:
> <form method="POST" action="RekrytServlet?id=login">
>
> The word "login" is a static that is sent as a part of the request
> for navigation purposes.  I don't want to use the GET method as it
> will display the password in the Location box.

     POST is generally preferred for sensitive data, but it is not
actually any more secure.  It's just less likely to lead to users
bookmarking a URL with their password in it.  However, this is
definitely the wrong way to do it.  When you do this, you'll have two
conflicting sets of parameters.  If you want to send "id=login", just
have the form include a tag like:

<INPUT TYPE=hidden NAME="id" VALUE="login">

     However, in general I don't recommend doing it this way.  Forget
the whole id parameter.  There're basically two ways to do it - the old
way and the right way.  The right way is to use filters, which were added
in the 2.3 servlet spec, but that may not be available.

     The old way, if you're required to use an older servlet engine
because of organizational constraints, is to: read up on HttpSession.
Build three methods besides doPost: alreadyLoggedIn(), loginUser(),
and buildLoginForm().

     The first cut, just have it store the login data to HttpSession,
then have it read the login data from data and print it (for testing).
When that's working reliably, take the section that reads the login
data and move it to alreadyLoggedIn(), and have it check to see if the
user has login data in their HttpSession, and return true or false.
Now do the third part, build a method that generates the HTML for the
login form.  Now make doPost() look sort of like:

     if (alreadyLoggedIn(HttpRequest req)) {
       // Do whatever it is you need to do
     }
     else {
       if (checkParameter("userid") && checkParameter("password")) {
         doLogin(HttpRequest req) ;
       }
       else {
         String loginForm = buildLoginForm() ;
         // Now do the usual output stuff to send the form to the user
       }
     }

     Of course, now that I look at it I can see obvious ways to clean
it up, like changing the alreadyLoggedIn() invocation into a guard
condition:

     if (checkParameter("userid") && checkParameter("password")) {
       doLogin(HttpRequest req) ;
     }
     if (!alreadyLoggedIn(HttpRequest)) {
        String loginForm = buildLoginForm() ;
        // Now do the usual output stuff to send the form to the user
        return ;
     }
     // If the user made it to this point they were either already logged
     // in or they just logged in now, so do whatever it is you need to do

     Of course there are some problems with this, depending on the
level of security you want:

     - If it's a high security site you should check for the level of
       encryption on the request and refuse login (and generate a
       warning page) if it's not there or it's too low.

     - If it's a very high security site you may want to see if that
       user was already logged in, and decide how to react to it
       (flush the old login, or lock the account, or refuse the new
       login, etc).

     - You also may want to keep some sort of timeout data in the
       HttpSession as well, expiring the session after five minutes of
       inactivity, to avoid the user walking away from a public
       terminal and leaving themeselves logged in (there are also some
       tricky bits to watch out for with form data being cached and
       reposted by the form).

     Now as for the right way to do it: find a servlet engine that
supports the 2.3 Servlet spec, specifically filters, and surf over to
egroups.com, look up the advanced-servlets discussion list, check the
archive for last week's discussion about filters and logins, and do it
that way.


> Okay, so when I use the POST method and let the form pull the
> trigger, the params from the form itself gets sent along, but if I
> enter the same URL in the Location box, the params will never be
> sent and thus return a null when the servlet tries to read them with
> the getParameter method. If this is the case, would I not get the
> null pointer exception when I enter the URL manually? Or is it
> something with that null vs empty string problem you mentioned?

     Not quite.  When you hardcode the param into the URL the entire
URL gets sent to the server and the server checks each GET style
request to see if there's a ? in the middle and encoded parameters to
the right of the ?.  When you target a POST at a URL with a ?id=login
in it, now you have two, possibly conflicting sources of parameter
data.  I vaguely recall reading somewhere in the last year that some
servlet engines might combine the two sets of data, but generally it
seems like the wrong way to do it, and I I definitely wouldn't count
on it.

     Maybe that's just my background in web CGI scripting talking,
though.  In the old CGI days (when the web was young and dinosaurs
still roamed the earth :-), typically the server forked a process to
run a CGI script.  The arguments were passed to the CGI script by
either storing the remainder of the URL in an environment variable
(for a GET style request) or feeding them to STDIN (for a POST style
request).  The first thing a CGI script had to do was parse the
arguments*.  Typically you looked for the environment
variable and parsed the data from there, or if you didn't see it in
the environment variable, you read STDIN.

     * (this was quickly abstracted away into standard libraries,
       though I think it's still a good idea to write your own
       argument parsing at least once, just to learn what's going on -
       that's not me being snobbish, either, I came onto the scene
       after the libraries all handled it, I had to write a custom
       parser to preserve parameter order for a specific job)

     However, on reflection even if it is just my own peculiar bias
causing that uneasy feeling, I still think it's a bad idea.  Just use
one or the other.  GET style requests are for requesting data, POST
style requests are for pushing data to the server.  GET style request
arguments were originally intended for things like clicking on an
image map (to send the X/Y coordinates of where you clicked).

Steven J. Owens
[EMAIL PROTECTED]

___________________________________________________________________________
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff SERVLET-INTEREST".

Archives: http://archives.java.sun.com/archives/servlet-interest.html
Resources: http://java.sun.com/products/servlet/external-resources.html
LISTSERV Help: http://www.lsoft.com/manuals/user/user.html

Reply via email to