31 min read

In this article Loiane Groner, author of Mastering Ext JS, talks about developing a login page for an application using Ext JS.

It is very common to have a login page for an application, which we can use to control access to the system by identifying and authenticating the user through the credentials presented by him/her. Once the user is logged in, we can track the actions performed by the user. We can also restrain access of some features and screens of the system that we do not want a particular user or even a specific group of users to have access to.

In this article, we will cover:

  • Creating the login page
  • Handling the login page on the server
  • Adding the Caps Lock warning message in the Password field
  • Submitting the form by pressing the Enter key
  • Encrypting the password before sending to the server

(For more resources related to this topic, see here.)

The Login screen

The Login window will be the first view we are going to implement in this project. We are going to build it step by step and it will have the following capabilities:

  • User will enter the username and password to log in
  • Client-side validation (username and password required to log in)
  • Submit the Login form by pressing Enter
  • Encrypt the password before sending to the server
  • Password Caps Lock warning (similar to Windows OS)
  • Multilingual capability

Except for the multilingual capability, we will implement all the other features throughout this topic. So at the end of the implementation, we will have a Login window that looks like the following:

So let’s get started!

Creating the Login screen

Under the app/view directory, we will create a new file named Login.js.In this file, we will implement all the code that the user is going to see on the screen.

Inside the Login.js file, we will implement the following code:

Ext.define(‘Packt.view.Login’, { // #1 extend: ‘Ext.window.Window’, // #2 alias: ‘widget.login’, // #3 autoShow: true, // #4 height: 170, // #5 width: 360, // #6 layout: { type: ‘fit’ // #7 }, iconCls: ‘key’, // #8 title: “Login”, // #9 closeAction: ‘hide’, // #10 closable: false // #11 });

On the first line (#1) we have the definition of the class. To define a class we use Ext.define, followed by parentheses (()), and inside the parentheses we first declare the name of the class, followed by a comma () and curly brackets ({}), and at the end a semicolon. All the configurations and properties (#2 to #11) go inside curly brackets.

We also need to pay attention to the name of the class. This is the formula suggested by Sencha in Ext JS MVC projects: App Namespace + package name + name of the JS file. we defined the namespace as Packt (configuration name inside the app.js file). We are creating a View for this project, so we will create the JS file under the view package/directory. And then, the name of the file we created is Login.js; therefore, we will lose the .js part and use only Login as the name of the View. Putting all together, we have Packt.view.Login and this will be the name of our class.

Then, we are saying that the Login class will extend from the Window class (#2), because we want it to be displayed inside a window, and not on any other component.

We are also assigning this class an alias (#3). The alias for a class that extends from a component always starts with widget., followed by the alias we want to assign. The naming convention for an alias is lowercase . It is also important to remember that the alias must be unique in an application. In this case we want to assign login as alias to this class so later we can instantiate this same class using its alias (that is the same as xtype). For example, we can instantiate the Login class using four different options:

  • Using the complete name of the class, which is the most used one:

    Ext.create(‘Packt.view.Login’);

  • Using the alias in the Ext.create method:

    Ext.create(‘widget.login’);

  • Using the Ext.widget, which is a shorthand way of using

    Ext.ClassManager.instantiateByAlias: Ext.widget(‘login’);

  • Using the xtype as an item of another component:

    items: [ { xtype: ‘login’ } ]

In this book we will use the first, third, and fourth options most of the time.

Then we have autoShow configured to true (#4). What happens with the window is that instantiating the component is not enough for displaying it. When we instantiate the window we will have its reference, but it will not be displayed on the screen. If we want it to be displayed we need to call the method show() manually. Another option is to have the autoShow configuration set to true. This way the window will be automatically displayed when we instantiate it.

We also have height (#5) and width (#6) of the window. We set the layout as fit (#7) because we want to add a form inside this window that will contain the username and password fields. And using the fit layout the form will occupy all the body space of the window. Remember that when using the fit layout we can only have one item as a child component.

We are setting an iconCls (#8) property to the window; this way we will have an icon of a key in the header of the window. We can also give a title for the window (#9), and in this case we chose Login. Following is the declaration of the key style used by the iconCls property:

.key { background-image:url(‘../icons/key.png’) !important; }

All the styles we will create to use as iconCls have a format like the preceding one.

And at last we have the closeAction (#10) and closable (#11) configurations. The closeAction configuration will tell if we want to destroy the window when we close it. In this case, we do not want to destroy it; we only want to hide it. The closable configuration tells if we want to display the X icon on the top-right corner of the window. As this is a Login window, we do not want to give this option for the user.

If you would like to, you can also add the resizable and draggable options as false. This will prevent the user to drag the Login window around and also to resize it.

So far, this will be the output we have. A single window with an icon at the top-left corner with a title Login :

The next step is to add the form with the username and password fields. We are going to add the following code to the Login class:

items: [ { xtype: ‘form’, // #12 frame: false, // #13 bodyPadding: 15, // #14 defaults: { // #15 xtype: ‘textfield’, // #16 anchor: ‘100%’, // #17 labelWidth: 60 // #18 }, items: [ { name: ‘user’, fieldLabel: “User” }, { inputType: ‘password’, // #19 name: ‘password’, fieldLabel: “Password” } ] } ]

As we are using the fit layout, we can only declare one child item in this class. So we are going to add a form (#12) and to make the form to look prettier, we are going to remove the frame property (#13) and also add padding to the form body (#14). The form’s frame property is by default set to false. But by default, there is a blue border that appears if we to do not explicitly add this property set to false.

As we are going to add two fields to the form, we probably want to avoid repeating some code. That is why we are going to declare some field configurations inside the defaults configuration of the form (#15); this way the configuration we declare inside defaults will be applied to all items of the form, and we will need to declare only the configurations we want to customize. As we are going to declare two fields, both of them will be of type textfield. The default layout of the form is the anchor layout, so we do not need to make this declaration explicit. However, we want both fields can occupy all the horizontal available space of the body of the form. That is why we are declaring anchor as 100% (#17). By default, the width attribute of the label of the TextField class is 100 pixels. It is too much space for a label User and Password, so we are going to decrease this value to 60 pixels (#18).

And finally, we have the user text field and the password text field. The configuration name is what we are going to use to identify each field when we submit the form to the server. But there is only one detail missing: when the user types the password into the field the system cannot display its value, we need to mask it somehow. That is why inputType is ‘password’ (#19) for the password field, as we want to display bullets instead of the original value, and the user will not be able to see the password value.

Now we have improved our Login window a little more. This is the output so far:

Client-side validations

The field component in Ext JS provides some client-side validation capability. This can save time and also bandwidth (the system will only make a server request when it is sure the information has passed the basic validation). It also helps to point out to the user where they have gone wrong in filling out the form. Of course, it is also good to validate the information again on the server side for security reasons, but for now we will focus on the validations we can apply to the form of our Login window.

Let’s brainstorm some validations we can apply to the username and password fields:

  • The username and password must be mandatory—how are going to authenticate the user without a username and password?
  • The user can only enter alphanumeric characters (A-Z, a-z, and 0-9) in both the fields.
  • The user can only type between 3 and 25 chars in the username field.
  • The user can only type between 3 and 15 chars in the password field.

So let’s add into the code the ones that are common to both fields:

allowBlank: false, // #20 vtype: ‘alphanum’, // #21 minLength: 3, // #22 msgTarget: ‘under’ // #23

We are going to add the preceding configurations inside the defaults configuration of the form, as they all apply to both the fields we have. First, both need to be mandatory (#20), we can only allow to enter alphanumeric characters (#21) and the minimum number of characters the user needs to input is three (#22). Then, a last common configuration is that we want to display any validation error message under the field (#23).

And the only validation customized for each field is that we can enter a maximum of 25 characters in the User field:

name: ‘user’, fieldLabel: “User”, maxLength : 25

And a maximum of 15 characters in the Password field:

inputType: ‘password’, name: ‘password’, fieldLabel: “Password”, maxLength : 15

After we apply the client validations, we will have the following output in case the user went wrong in filling out the Login window:

If you do not like it, we can change the place where the error message appears. We just need to change the msgTarget value. The available options are: title, under, side, and none. We can also show the error message as a tooltip (qtip) or display it in a specific target (inner HTML of a specific component).

Creating custom VTypes

Many systems have a special format for passwords. Let’s say we need the password to have at least one digit (0-9), one letter lowercase, one letter uppercase, one special character (@, #, $, %, and so on) and its length between 6 and 20 characters.

We can create a regular expression to validate that the password is entering into the app. And to do this, we can create a custom VType to do the validation for us. Creating a custom VType is simple. For our case, we can create a custom VType called passRegex:

Ext.apply(Ext.form.field.VTypes, { customPass: function(val, field) { return /^((?=.*d)(?=.*[a-z])(?=.*[A-Z])
(?=.*[@#$%]).{6,20})/.test(val); }, customPassText: ‘Not a valid password.
Length must be at least 6 characters and maximum of 20Password
must contain one digit, one letter lowercase, one letter uppercase,
onse special symbol
@#$% and between 6 and 20 characters.’, });

customPass is the name of our custom VType, and we need to declare a function that will validate our regular expression. customPassText is the message that will be displayed to the user in case the incorrect password format is entered.

The preceding code can be added anywhere on the code, inside the init function of a controller, inside the launch function of the app.js, or even in a separate JavaScript file (recommended) where you can put all your custom VTypes.

To use it, we simply need to add vtype: ‘customPass’ to our Password field.

To learn more about regular expressions, please visit http://www.regular-expressions.info/.

Adding the toolbar with buttons

So far we have created the Login window, which contains a form with two fields and it is already being validated as well. The only thing missing is to add the two buttons: cancel and submit .

We are going to add the buttons as items of a toolbar and the toolbar will be added on the form as a docked item. The docked items can be docked to either on the top, right, left, or bottom of a panel (both form and window components are subclasses of panel). In this case we will dock the toolbar to the bottom of the form. Add the following code right after the items configuration of the form:

dockedItems: [ { xtype: ‘toolbar’, dock: ‘bottom’, items: [ { xtype: ‘tbfill’ //#24 }, { xtype: ‘button’, // #25 itemId: ‘cancel’, iconCls: ‘cancel’, text: ‘Cancel’ }, { xtype: ‘button’, // #26 itemId: ‘submit’, formBind: true, // #27 iconCls: ‘key-go’, text: “Submit” } ] } ]

If we take a look back to the screenshot of the Login screen we first presented at the beginning of this article, we will notice that there is a component for the translation/multilingual capability. And after this component there is a space and then we have the Cancel and Submit buttons. As we do not have the multilingual component yet, we can only implement the two buttons, but they need to be at the right end of the form and we need to leave that space. That is why we first need to add a toolbar fill component (#24), which is going to instruct the toolbar’s layout to begin using the right-justified button container.

Then we will add the Cancel button (#25) and then the Submit button (#26). We are going to add icons to both buttons (iconCls) and later, when we implement the controller class, we will need a way to identify the buttons. This is why we assigned itemId to both of them.

We already have the client validations, but even with the validations, the user can click on the Submit button and we want to avoid this behavior. That is why we are binding the Submit button to the form (#27); this way the button will only be enabled if the form has no error from the client validation.

In the following screenshot, we can see the current output of the Login form (after we added the toolbar) and also verify the behavior of the Submit button:

Running the code

To execute the code we have created so far, we need to make a few changes in the app.js file.

First, we need to declare views we are using (only one in this case). Also, as we are going to instantiate using the Login class’ xtype, we need to declare this class in the requires declaration:

requires: [ ‘Packt.view.Login’ ], views: [ ‘Login’ ],

And the last change is inside the launch function. now we only need to replace the console.log message with the Login instance (#1):

splashscreen.next().fadeOut({ duration: 1000, remove:true, listeners: { afteranimate: function(el, startTime, eOpts ){ Ext.widget(‘login’); // #1 } } });

Now the app.js is OK and we can execute what we have implemented so far!

Using itemId versus id Ext.Cmp is bad!

Before we create the controller, we will need to have some knowledge about Ext.ComponentQuery selectors. And in this topic we will discuss a subject to help us to understand better why we took some decisions while creating the Login window and why we are going to take some other decisions on the controller topic.

Whenever we can, we will always try to use the itemId configuration instead of id to uniquely identify a component. And here comes the question, why?

When using id, we need to make sure that id is unique, and none of all the other components of the application has the same id. Now imagine the situation where you are working with other developers of the same team and it is a big application. How can you make sure that id is going to be unique? Pretty difficult, don’t you think? And this can be a hard task to achieve.

Components created with an id may be accessed globally using Ext.getCmp, which is a short-hand reference for Ext.ComponentManager.get.

Just to mention one example, when using Ext.getCmp to retrieve a component by its id, it is going to return the last component declared with the given id. And if the id is not unique, it can return the component that you are not expecting and this can lead into an error of the application.

Do not panic! There is an elegant solution, which is using itemId instead of id.

The itemId can be used as an alternative way to get a reference of a component. The itemId is an index to the container’s internal MixedCollection, and that is why the itemId is scoped locally to the container. This is the biggest advantage of the itemId.

For example, we can have a class named MyWindow1, extending from window and inside this class we can have a button with item ID submit. Then we can have another class named MyWindow2, also extending from window, and also with a button with item ID submit.

Having two item IDs with the same value is not an issue. We only need to be careful when we use Ext.ComponentQuery to retrieve the component we want. For example, if we have a Login window whose alias is login and another screen called the Registration window whose alias is registration. Both the windows have a button Save whose itemId is save. If we simply use Ext.ComponentQuery.query(‘button#save’), the result will be an array with two results. However, if we narrow down the selector even more, let’s say we want the Login window’s Save button, and not the Registration window’s Save button, we need to use Ext.ComponentQuery.query(‘login button#save’), and the result will be a single item, which is exactly we expect.

You will notice that we will not use Ext.getCmp in the code of our project. Because it is not a good practice; especially for Ext JS 4 and also because we can use itemId and Ext.ComponentQuery instead. We will understand Ext.ComponentQuery better during the next topic.

Creating the login controller

We have created the view for the Login screen so far. As we are following the MVC architecture, we are not implementing the user interaction on the View class. If we click on the buttons on the Login class, nothing will happen because we have not yet implemented this logic. We are going to implement this logic now on the controller class.

Under the app/controller directory, we will create a new file named Login.js. In this file we will implement all the code related to the events management of the Login screen.

Inside the Login.js file we will implement the following code, which is only a base of the controller class we are going to implement:

Ext.define(‘Packt.controller.Login’, { // #1 extend: ‘Ext.app.Controller’, // #2 views: [ ‘Login’ // #3 ], init: function(application) { // #4 this.control({ // #5 }); } });

As usual, on the first line of the class we have its name (#1). Following the same formula we used for the view/Login.js we will have Packt (app namespace) + controller (name of the package) + Login (which is the name of the file), resulting in Packt.controller.Login.

Note that that the controller JS file (controller/Login.js) has the same name as view/Login.js, but that is OK because they are in a different package. It is good to use a similar name for the views, models, stores and controllers because it is going to be easier to maintain the project later. For example, let’s say that after the project is in production, we need to add a new button on the Login screen. With only this information (and a little bit of MVC concept knowledge) we know we will need to add the button code on the view/Login.js file and listen to any events that might be fired by this button on the controller/Login.js. Easier maintainability is also a great pro of using the MVC architecture.

The controller classes need to extend from Ext.app.Controller (#2), so we will always use this parent class for our controllers.

Then we have the views declaration (#3), which is where we are going to declare all the views that this controller will care about. In this case, we only have the Login view so far. We will add more views later on this article.

Next, we have the init method declaration (#4). The init method is called before the application boots, before the launch function of Ext.application (app.js). The controller will also load the views, models, and stores declared inside its class.

Then we have the control method configured (#5). This is where we are going to listen to all events we want the controller to react. And as we are coding the events fired by the Login window and its child components, this will be our scope in this controller.

Adding the controller to app.js

Now that we already have a base of the login controller, we need to add it to the app.js file.

We can remove this code, since the controller will be responsible for loading the view/Login.js file for us:

requires: [ ‘Packt.view.Login’ ], views: [ ‘Login’ ], And add the controllers declaration: controllers: [ ‘Login’ ],

And as our project is only starting, declaring the views on the controller classes will help us to have a code more organized, as we do not need to declare all the application’s views in the app.js file.

Listening to the button click event

Our next step now is to start listening to the Login window events. First, we are going to listen to the Submit and Cancel buttons.

We already know that we are going to add the listeners inside the this.control declaration. The format that we need to use is the following:

‘Ext.ComponentQuery selector’: { eventWeWantToListenTo: functionOrMethodWeWantToExecute }

First, we need to pass the selector that is going to be used by the Ext.ComponentQuery class to find the component. Then we need to list the event that we want to listen to. And then, we need to declare the function that is going to be executed when the event we are listening to is fired, or declare the name of the controller method that is going to be executed when the event is fired. In our case, we are going to declare the method only for code organization purposes.

Now let’s focus on finding the correct selector for the Submit and Cancel buttons. According to Ext.ComponentQuery API documentation, we can retrieve components by using their xtype (if you are already familiar with jQuery, you will notice that Ext.ComponentQuery selectors are very similar to jQuery selectors’ behavior). Well, we are trying to retrieve two buttons, and their xtype is button. We try then the selector button. But before we start coding, let’s make sure that this is the correct selector to avoid us to change the code all the time when trying to figure out the correct selector. There is one very useful tip we can try: open the browser console (command editor), type the following command, and click on Run :

Ext.ComponentQuery.query(‘button’);

As we can see in the screenshot, it returned an array of the buttons that were found by the selector we used, and the array contains six buttons; too many buttons and it is not what we want. We want to narrow down to the Submit and Cancel buttons.

Let’s try to draw a path of the Login window using the components xtype we used:

We have a Login window (xtype: login or window), inside the window we have a form (xtype: form), inside the form we have a toolbar (xtype: toolbar), and inside the toolbar we have two buttons (xtype: button). Therefore, we have loginformtoolbarbutton. However, if we use loginformbutton we will have the same result, because we do not have any other buttons inside the form. So we can try the following command:

Ext.ComponentQuery.query(‘login form button’);

So let’s try this last selector on the command editor:

Now the result is an array of two buttons and these are the buttons that we are looking for! There is still one detail missing: if we use the login form button selector, it will listen to the click event (which is the event we want to listen to) of both buttons. When we click on the Cancel button one thing should happen (reset the form) and when we click on the Submit button, another thing should happen (submit the form to the server to validate the login). So we still want to narrow down the selector even more, until it returns the Cancel button and another selector that will return the Submit button.

Going back to the view/Login code, notice that we declared a configuration named itemId to both buttons. We can use these itemId configurations to identify the buttons in a unique way. According to the Ext.ComponentQuery API docs, we can use # as a prefix of itemId. So let’s try the following command on the command editor to get the Submit button reference:

Ext.ComponentQuery.query(‘login form button#submit’);

The output will be only one button as we expect:

Now let’s try the following command to retrieve the Cancel button reference:

Ext.ComponentQuery.query(‘login form button#cancel’);

The output will be only one button as we expect:

So now we have the selectors that we were looking for! Console command editor is a great tool and using it can save us a lot of time when trying to find the exact selector that we want, instead of coding, testing, not the selector we want, code again, test again, and so on.

Could we use only button#submit or button#cancel as selectors? Yes, we could use a shorter selector. However, it would work perfectly for now. As the application grows and we declare many more classes and buttons, the event would be fired for all buttons that have the itemId named submit or cancel and this could lead to an error in the application. We always need to remember that itemId is scoped locally to the container. By using login form button as the selector, we make sure that the event will come from the button from the Login window.

So let’s implement the code inside the controller class:

init: function(application) { this.control({ “login form button#submit”: { // #1 click: this.onButtonClickSubmit // #2 }, “login form button#cancel”: { // #3 click: this.onButtonClickCancel // #4 } }); }, onButtonClickSubmit: function(button, e, options) { console.log(‘login submit’); // #5 }, onButtonClickCancel: function(button, e, options) { console.log(‘login cancel’); // #6 }

In the preceding code, we have first the listener to the Submit button (#1), and on the following line we say that we want to listen to the click event, and then, when the click event of the Submit button is fired, the onButtonClickSubmit method should be executed (#2).

Then we have the same for the Cancel button: we have the listener to the Cancel button (#3), and on the following line we say that we want to listen to the click event, and then, when the click event of the Cancel button is fired, the onButtonClickCancel method should be executed (#4).

Next, we have the declaration of the methods onButtonClickSubmit and onButtonClickCancel. For now, we are only going to output a message on the console to make sure that our code is working. So we are going to output login submit (#5) in case the user clicks on the Submit button, and login cancel (#6) in case the user clicks on the Cancel button.

But how do you know which are the parameters the event method can receive? You can find the answer to this question in the documentation. If we take a look at the click event in the documentation, this is what we will find:

This is exactly what we declared. For all the other event listeners, we will go to the docs and see which are the parameters the event accepts, and then list them as parameters in our code. This is also a very good practice. We should always list out all the arguments from the docs, even if we are only interested in the first one. This way we always know that we have the full collection of the parameters, and this can come very handy when we are doing maintenance of the application.

Let’s go ahead and try it. Click on the Cancel button and then on the Submit button. This should be the output:

Cancel button listener implementation

Let’s remove the console.log messages and add the code we actually want the methods to execute. First, let’s work on the onButtonClickCancel method. When we execute this method, we want it to reset the form.

So this is the logic sequence we want to program:

  1. Get the Login form reference.
  2. Call the method getForm, which is going to return the form basic class.
  3. Call the reset method to reset the form.

The form basic class provides input field management, validation, submission, and form loading services. The Ext.form.Panel class (xtype: form) works as the container, and it is automatically hooked up with an instance of Ext.form.Basic. That is why we need to get the form basic reference to call the reset method.

If we take a look at the parameters we have available on the onButtonClickCancel method, we have: button, e, and options, and none of them provides us the form reference.

So what can we do about it? We can use the up method from the Button class (inherited from the AbstractComponent class). With this method, we can use a selector to try to retrieve the form. The up method navigates up the component hierarchy, searching from an ancestor container that matches the passed selector.

As the button is inside a toolbar that is inside the form we are looking for, if we use button.up(‘form’), it will retrieve exactly what we want. Ext JS will see what is the first ancestor in the hierarchy of the button and will find a toolbar. Not what we are looking for. So it goes up again and it will find a form, which is what we are looking for.

So this is the code that we are going to implement inside the onButtonClickCancel method:

button.up(‘form’).getForm().reset();

Some people like to implement the toolbar inside the window instead of the form. No problem at all, it is only a matter of how you like to implement it. In this case, if the toolbar that contains the Submit button is inside the Window class we can use:

button.up(‘window’).down(‘form’).getForm().reset()

And we will have the same result!

Submit button listener implementation

Now we need to implement the onButtonClickSubmit method. Inside this method, we want to program the logic to send the username and password values to the server so that the user can be authenticated.

We can implement two programming logics inside this method: the first one is to use the submit method that is provided by the form basic class and the second one is to use an Ajax call to submit the values to the server. Either way we will achieve what we want to do. However, there is one detail that we need to know prior to making this decision: if using the submit method of the form basic class, we will not be able to encrypt the password before we send it to the server, and if we take a look at the parameters sent to the server, the password will be a plain text, and this is not good. Using the Ajax request will result the same; however, we can encrypt the password value before sending to the server. So apparently, the second option seems better and that is the one that we will implement.

So to summarize, following are the steps we need to perform in this method:

  • Get the Login form reference
  • Get the Login window reference (so that we can close it once the user has been authenticated)
  • Get the username and password values from the form
  • Encrypt the password
  • Send login information to the server
  • Handle the server response
    • If user is authenticated display application
    • If not, display an error message

First, let’s get the references that we need:

var formPanel = button.up(‘form’), login = button.up(‘login’), user = formPanel.down(‘textfield[name=user]’).getValue(), pass = formPanel.down(‘textfield[name=password]’).getValue();

To get the form reference, we can use the button.up(‘form’) code that we already used in the onButtonClickCancel method; to get the Login window reference we can do the same thing, only changing the selector to login or window. Then to get the values from the User and Password fields we can use the down method, but this time the scope will start from the form reference. For the selector we will use the text field xtype, and to make sure we are retrieving the text field we want, we can create an itemId attribute, but there is no need for it. We can use the name attribute since the user and password fields have different names and they are unique within the Login window. To use attributes within a selector we must wrap it in brackets.

The next step is to submit the values to the server:

if (formPanel.getForm().isValid()) { Ext.Ajax.request({ url: ‘php/login.php’, params: { user: user, password: pass } }); }

If we try to run this code, the application will send the request to the server, but we will get an error as the response because we do not have the login.php page implemented yet. That’s OK because we are interested in other details right now.

With Firebug or Chrome Developer Tools enabled, open the Net tab and filter by the XHR requests. Make sure to enter a username and password (any valid value so that we can click on the Submit button). This will be the output:

We still do not have the password encrypted. The original value is still being displayed and this is not good. We need to encrypt the password.

Under the app directory, we will create a new folder named util where we are going to create all the utility classes. We will also create a new file named MD5.js; therefore, we will have a new class named Packt.util.MD5. This class contains a static method called encode and this method encodes the given value using the MD5 algorithm. To understand more about the MD5 algorithm go to http://en.wikipedia.org/wiki/MD5. As Packt.util.MD5 is big, we will not list its code here, but you can download the source code of this book from http://www.packtpub.com/mastering-ext-javascript/book or get the latest version at https://github.com/loiane/masteringextjs).

If you would like to make it even more secure, you can also use SSL and ask for a random salt string from the server, salt the password and hash it. You can learn more about it at one the following URLs: http://en.wikipedia.org/wiki/Transport_Layer_Security and http://en.wikipedia.org/wiki/Salt_(cryptography).

A static method does not require an instance of the class to be able to be called. In Ext JS, we can declare static attributes and methods inside the static configuration. As the encode method from Packt.util.MD5 class is static, we can call it like Packt.util.MD5.encode(value);.

So before Ext.Ajax.request, we will add the following code:

pass = Packt.util.MD5.encode(pass);

We must not forget to add the Packt.util.MD5 class on the controller’s requires declaration (the requires declaration is right after the extend declaration):

requires: [ ‘Packt.util.MD5’ ],

Now, if we try to run the code again, and check the XHR requests on the Net tab, we will have the following output:

The password is encrypted and it is much safer now.

LEAVE A REPLY

Please enter your comment!
Please enter your name here