sabato 21 febbraio 2015

Localization with Angular.JS

In a previous post covering the use of Angular.JS on an ASP.NET (or better, DotNetNuke) web app, a was wondering how to solve the problem of localize the js content.

In fact I discovered pretty soon that many strings of the presentation layer were specified inside the js file, defining the angular app, controller, directive,....

So my first thought was to create a specific handler in order to generate the javascript at runtime so that I would have the capability to use the native localization management of ASP.NET or DotNetNuke.

IMHO the handler would have as many cons than pro, or even worst; for example, every js file would have been addressed by the unique handler, breaking the easy file organization of each DNN module or ascx control, ...: much work for a small problem.

So I passed to another approach:
why not concentrate all the strings to localize in a js object inside the ascx file?
the Angular.JS app (controller/directive,...) would be kept in a separate pure js file, with the capability to access the variable once on the client's browser.

The solution is composed by:
1) a method to run on load, in a base class of the module (or User control), with a couple of properties override-able in the specialized module class.

     protected void LoadResourcesToJavascript()
        {
            if (this.ResourceKeysToJavascript.Count() > 0)
            {
                System.Text.StringBuilder sb = new System.Text.StringBuilder();
                sb.Append("var " + this.ResourceJSVariableName + " = {};\n");

                foreach (String s in this.ResourceKeysToJavascript)
                {
                    sb.Append(this.ResourceJSVariableName + "." + s + "= '" + Localization.GetString(s + ".Text", LocalResourceFile) + "';\n");
                }

                Page.ClientScript.RegisterClientScriptBlock(this.GetType(), this.ResourceJSVariableName + "Resources", sb.ToString(), true);
            }
        }

        protected virtual List ResourceKeysToJavascript
        {
            get
            {
                return new List();
            }
        }
        protected virtual String ResourceJSVariableName
        {
            get
            {
                return this.ID;
            }

        }

Note: I use the DNN method to get the localized string. Change it in case of standard ASP.NET project.
Note: The javascript variable name is the control's ID, but it can be specialized in the inherited module class.

2) in the inherited module / user control specialize the ResourceKeyToJavascript list with the resource string required in the javascript.

 protected override List ResourceKeysToJavascript
        {
            get
            {
                return new List() { 
                                "ConfirmRemoving",
                                "SailingName",
                                "Types",
                                "UnableToFindFriend",
                                "Saved",
                                "Error"};
            }
        }

3) in javascrpit file use the variable name (ASP.NET control's ID) to access the single resource strings:

var str = CrewMemberCollectionV2View.ConfirmRemoving;
if (confirm(str.replace("{sailingName}", entity.SailingName))) {
     //do something  
}

4) last but not least, use the standard resx files to add the required resource strings.

Security using client-side javascript frameworks

In a previous post I put the focus on the security of Angular.JS.

I found a quite easy way to solve this problem:

the problem simply... does not arise.

I am going to explain a bit deeper this concept.

Usually security has to address one main goal: allow to access data/services only if the user has the right authorization.
There is a second, less important goal: adapt the presentation layer to the gained authorization.

Example: if I do not have the the authorization to change the info in a form, the "save button" should be absent on the page!

IMHO this is the real difference between standard "server-side-generated" page (php, asp.net,....) and "client-side-generated" page (Angular.JS,...); this difference can be summarized in this question:

"Who is going to decide if the button should or should not be shown?"

The first solution solve the complete security logic server side, sending to the client only the strictly necessary functions (if not authorized, the server will not even send the the button to the page), while the second solution delegates part (even significant one) of the security logic to client side.

This means that, Angular.JS (as every client side technology) can not solve the security issue itself: all the security logic has to be addressed by separate APIs entitle to check every service exchange among client web page and server web app.

But,even if I put in place this logic (server or client side) I should not forget to put in place the main security check: verify that the operation put in place is allowed!

Conclusion:

Working with client side logic helps a lot to focus on security issue leading to the correct sw architecture, and avoiding to mix up the main security goal with the secondary one.

My first time with Angular.js


I have started learning Angular.JS from scratch and here my first impressions:
  • Very coll (impressive!)
  • A real way to easy down the UI interface (my nightmare!)
  • It seems simple... too simple...
  • Yes, but wait... remember... nothing more than the presentation layer.
I was worried by a couple of things:

  • how to use security in Angular JS;
  • how to localize the strings that have to be set during js runtime.
I am going to explain how I solved these two worries in my next posts.


My first "test projects" for practicing on Angular.JS were focused on:

  • simplest ng-module in order to receive info via json and render them to the page;
  • simplest form bidirectional (coming / going to db);
  • UI grid;
  • Google Map (have to try!!);
  • put everything in DotNetNuke!
I found this link particularly helpful:
angular-ui.github.io


I found a quite easy way to solve the second problem (I am going to write something about that in another post).

The first problem was solved pretty soon:
the problem simply... does not arise.

I am going to explain a bit deeper this concept.

Usually security has to address one main goal: allow to access data/services only if the user has the right authorization.
There is a second, less important goal: adapt the presentation layer to the gained authorization.

Example: if I do not have the the authorization to change the info in a form, the "save button" should be absent on the page!

IMHO this is the real difference between standard "server-side-generated" page (php, asp.net,....) and "client-side-generated" page (Angular.JS,...); this difference can be summarized in this question:

"Who is going to decide if the button should or should not be shown?"

The first solution solve the complete security logic server side, sending to the client only the strictly necessary functions (if not authorized, the server will not even send the the button to the page), while the second solution delegates part (even significant one) of the security logic to client side.

This means that, Angular.JS (as every client side technology) can not solve the security issue itself: all the security logic has to be addressed by separate APIs entitle to check every service exchange among client web page and server web app.

But,even if I put in place this logic (server or client side) I should not forget to put in place the main security check: verify that the operation put in place is allowed!

Conclusion:

Working with client side logic helps a lot to focus on security issue leading to the correct sw architecture, and avoiding to mix up the main security goal with the secondary one.