I've been coding away
for several days on some old web-login logic
I had implemented in littleware
to work in web applications with JSF-managed
UX.
I'm updating the code for use
in apps where a javascript program manages the user experience.
I've been thinking lately about
the similarities and differences between the two application architectures.
The first difference between the two designs is in deployment.
The old JSF architecture relied on JSF and JSP templates
managed by the server, so I would usually bundle up the
entire application in a .war file, and deploy it to some
glassfish
or tomcat or whatever
container. The user interacted with the application
by clicking links and submitting forms that moved
the browser between web pages rendered by the server.
I'm trying to structure the newer code so that
most client-side assets (javascript, CSS, hadlebar templates, ...)
are served as static files from S3.
The user's in-browser interactions with the application trigger events
that are handled by javascript event-handlers.
The javascript code running in the user's browser can access remote services via
cross-origin
AJAX requests.
There are various CORS servlet filters open sourced online that take
care of setting the HTTP response headers that browsers look
for; today I grabbed this one
posted by some Ebay coders to github - hopefully it works.
In the login code,
both the old and new setups rely on a request filter
(javax.servlet.Filter)
to intercept unauthenticated client requests.
The old code would intercept an unauthenticated page-load request, and
forward the request on the server to a login page via
RequestDispatcher.forward.
The new code intercepts unauthenticated AJAX requests to JSON services,
and responds to the javascript client with an
HTTP 401
(unauthorized) response, and relies upon the javascript code on the client
to initiate a login process that eventually authenticates with
the server by submitting credentials to a login AJAX service.
Finally - in the older applications I had the bad habit of tracking session state
on the server via beans stashed in container-managed in-memory
session.
Tracking user data in-memory on a particular server required that
a client continued to interact with the same server it began a session with.
In-memory session state also made it difficult to partition a server's functionality between different
endpoints. In other words - if I had a server that implemented some functionality "ABC",
and I later decided that I would like to split the functionality on that server
(or server cluster) between separate "A", "B", and "C" servers (or clusters), then
it would be hard to do that if the code relied on shared in-memory session state.
Anyway, the new code avoids session state on the server - instead it relies on the client-side
javascript code to track session state in most cases, and transient cookies in a few
others.
In the end - I get to throw away a bunch of crazy server-side JSF beans and templates, and
replace them with javascript modules and REST services.