Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to safely process a login using AngularJS

I'm new to Angular. I'm developing a simple login form whereby the username typed is compared to a username returned from a JSON query. If a match is found, the login is processed.

I feel the way I'm doing it isn't safe, am I right in thinking that the returned JSON string could be accessed through the browser's console?

I will be adding password check to this as well in the near future, once I understand how to properly go about this.

I would like pointing in the right direction to approach the issue of user login the Angular way.

app.js

angular.module('userApp', ["ngResource"]).

config(['$routeProvider', function($routeProvider) {
    $routeProvider.
        when('/login', {templateUrl: 'partials/login.html',   controller: LoginCtrl}).
        when('/loggedin', {templateUrl: 'partials/user-admin.html', controller: UserCtrl}).
        otherwise({redirectTo: '/login'});
}],[ '$locationProvider', function($locationProvider) {
    $locationProvider.html5Mode = true;
}]).

factory("User", function($resource) {
    return $resource("users/:userId.json", {}, {
        query: {method: "GET", params: {userId: "users"}, isArray: true}
    });
});

controllers.js

function LoginCtrl($scope, $route, $routeParams, $location, User) {
    $scope.users = User.query();
    $scope.loginUser = function() {
        var loggedin = false;
        var totalUsers = $scope.users.length;
        var usernameTyped = $scope.userUsername;

        for( i=0; i < totalUsers; i++ ) {
            if( $scope.users[i].name === usernameTyped ) {
                loggedin = true;
                break;
            }
        }

        if( loggedin === true ) {
            alert("login successful");
            $location.path("/loggedin");
        } else {
            alert("username does not exist")
        }
    }
}
like image 252
Fisu Avatar asked Feb 07 '13 15:02

Fisu


1 Answers

Yes, you are right - this is not safe. NEVER do such things:

  • NEVER store plain passwords in database (like "my_password_123"
  • NEVER return any sort of sensitive information to the client and perform secret computations in JavaScript
  • NEVER use simple password comparison (providedPassword == stored password) in server or client code
  • NEVER use unsecure (http) layer - use safe one (HTTPS) instead

A proper way of doing this is following:

  1. Generate Hashed value of password on store it in DB. Make sure to use a strong hashing algorithm and salted passwords. At the time of writing this reply SHA-256 would be enough, but make sure to check if it's still considered safe.
  2. Wire SSL certificate to get HTTPS support, that way noone will spy on what user sends to your server
  3. User enters username+password and sends them to your code on the server. On the server you compute SHA-1 hash and compare it against the stored value in DB. Then you send back the RESULT of authentication to the client and keep the track of it on the server by persistent session.

Please keep in mind that most of this stuff is done by some security frameworks, like Spring Security. I wouldn't recommend doing it all from scratch, as the topic of security is vast and it's easy to make a mistake that can be used by malicious users.

like image 172
ŁukaszBachman Avatar answered Sep 18 '22 22:09

ŁukaszBachman