Saturday, February 11, 2017

Heroes turned into Frankenstein (part I)

Starting at Tour of Heroes.  In my last post I had just redone my tour of heroes app for the newly released angular (angular2, 4?, whatever).  I had added a spring boot back end for the heroes service and all went well.  But what I really wanted was do a deep-ish dive with angular-cli and the angular router.  This led down a rabbit hole of exploration into the angular ecosystem.  I have arrived at the other end with some interesting (to me anyway) technology findings and an overall appreciation for where angular currently is from a framework maturity level.  This blog entry will document some of that discovery.  The source for client and server is on my github account.

First stop: Security. For some reason I take a somewhat masochistic interest in web security.  I don't really enjoy working in that space but I never feel like I can start even a play project without solving this problem of authentication and authorization.   As a learning exercise I decided to implement a JWT (json web token) approach with the goal of keeping my backend as stateless as possible.

JWT Server.  As there are two sides to this coin, server and client, I started with the server.  I'm using spring boot and was hoping the spring security project provided a module out of the box for JWT.  No such luck.  I ended up utilizing a series of web posts to learn about implementing the JWT handling with spring security.  Pretty much my entire server side JWT handling ended up being lifted from this repo on github.  It uses spring security and plugs in JWT handling in the right spots.  I have a simple User/Authority/UserAuthority set of tables in Postgresql that I use for authn/authz.  I then used the JWT handling code from the repo to manage token creation, handling and validation within a filter.

JWT Client. I next turned to angular.  I had already implemented routing within the app and added a route/component to log in.  I used the angular2-jwt library to help implement the passing of the JWT token on all REST calls to the server.  The general idea with JWT is that once the user is logged in, all http calls have the token attached (cookie or header) from the client side and the server (in my case a filter on spring boot) will pull the token and validate/authenticate the user.  Angular2-jwt accomplishes this on the client by providing an AuthHttp object which takes place of the normal http object through which you make your rest calls.  AuthHttp just wraps http and adds the token to the call.  I currently store the token in local storage.  This has the weird effect of never logging me out.  Somewhere the expiration time is being ignored, but I'll leave that and the large topic of JWT for another blog post.

Angular-cli, routes, and components.  When I first started working on this play application the router code generation had just been pulled from angular-cli with the promise that it would show back up.  Apparently routing had changed from router version 2 to 3 and it was very different and blah.  What it meant for me was that as I generated components for my application using "ng g c my-component",  I would have to manually wire in the routes.  Not really a big deal. But, as I started looking into the routing generation, I discovered that there was a way to lazy load an entire module of components via a routing subset.   This is kind of interesting.  Knowing that your app is gonna be pulling LOTS of javascript, being able to segment off a module that will be downloaded on demand is pretty awesome.  Not only that, but through a massive googling session, I had run across someone mentioning that the generation of the code to pull this off was still in angular-cli but was not documented.  It turn out that you can invoke "ng g m my-module --routing" and angular will generate the module, component, and set up the routes array.  Just a little wiring from the main route would set up the newly generated module to be lazy loaded.  The simplest example of this in my source is the app routing module and comp2 routing module.  As I am new to TypeScript and not what one would call a proficient Javascript developer, I stumbled for over a week as to the export syntax to achieve this load on demand module approach which culminated in my public a-ha moment on Stack Overflow.  There was immense satisfaction in seeing this load on demand actually work in chrome, seeing the webpacked module only pull down when needed.  Good stuff.

More to come.  Just now realizing I have too much to post in just a single blog entry so I'll leave off here.  In my next post I hope to include my work with different grid/table components,  treeview components, angular forms,  bootstrap and material styling, prime-ng components and a whole lot around websockets and STOMP protocol. Maybe 2 more posts!

Part II here.

No comments: