+3

Độ an toàn của mật khẩu trong AngularJS

Trong hướng dẫn này, mình sẽ tạo một form đăng ký đơn giản với các trường chỉ có tên, email và mật khẩu. Mình sẽ sử dụng demo để ước lượng sức mạnh của mật khẩu trong biểu mẫu và cũng cung cấp phản hồi trực quan. Mình cũng sẽ sử dụng AngularJS để kết nối dữ liệu hai chiều dễ dàng.

Tại sao phải đo mật độ mật khẩu?

  • Mật khẩu thường được sử dụng để xác thực người dùng trong hầu hết các ứng dụng web và do đó yêu cầu phải lưu mật khẩu một cách an toàn.
  • Mặc dù băm mật khẩu là một bước tuyệt vời để bảo mật mật khẩu, người dùng vẫn đặt ra một thách thức lớn đối với việc bảo mật mật khẩu. Một người dùng sử dụng một từ rất phổ biến cho mật khẩu làm cho nỗ lực của hashing vô ích, vì một cuộc tấn công có thể crack mật khẩu như vậy trong một thời gian rất ngắn. Nnếu cơ sở hạ tầng rất tinh vi được sử dụng cho cuộc tấn công, nó thậm chí có thể mất một phần nghìn giây, tùy thuộc vào mật khẩu phức tạp hoặc chiều dài.
  • Nhiều ứng dụng web ngày nay như Google, Twitter, Dropbox ... nhấn mạnh vào người dùng có mật mã mạnh mẽ hoặc bằng cách đảm bảo độ dài mật khẩu tối thiểu hoặc sự kết hợp của các ký tự chữ và số có thể là ký hiệu trong mật khẩu.
  • Làm thế nào để đo được sức mạnh mật khẩu? Dropbox phát triển một thuật toán cho một ước tính mật độ thực tế lấy cảm hứng từ bánh quy mật khẩu. Thuật toán này được đóng gói trong một thư viện Javascript được gọi là demo. Ngoài ra, gói chứa một từ điển của các từ tiếng Anh thường dùng, tên và mật khẩu. Bắt đầu Trước khi mình bắt đầu hướng dẫn, mình sẽ tải về tất cả các phụ thuộc chúng ta cần sử dụng trình quản lý gói Bower. Nếu bạn chưa có Bower trong hệ thống của mình, bạn có thể theo Bower Installation Guide. Chạy lệnh sau để cài đặt tất cả các phụ thuộc cho hướng dẫn.
bower install demo angularjs#1.5.9 bootstrap

Thư mục gốc phải chứa hai thư mục và một tệp tin.

  • assets folder
  • bower_components folder
  • index.html file Cấu trúc thư mục cho dự án của chúng ta trông giống như ảnh chụp màn hình sau - bạn có thể tạo thư mục và thư mục theo yêu cầu. Khởi đầu bằng HTML Hãy bắt đầu bằng cách thêm các đánh dấu cơ bản cho trang trong tệp index.html. Mình sẽ liên kết đến các tệp Bootstrap - bootstrap.min.css và bootstrap-theme.min.css và khung angular.min.js từ thư mục bower_components của mình. Mình cũng sẽ liên kết tới các tệp css và js của dự án của mình. Xem mã sau cho đánh dấu HTML cơ bản của trang của mình.
<!-- index.html -->

<!DOCTYPE html>
<html class="no-js">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Password Strength</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css">
        <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap-theme.min.css">
        <link rel="stylesheet" href="assets/css/main.css">
    </head>
    <body>
        <div class="main-container">
        <div class="form-container">
            <form action="" method="POST" role="form">
                <legend class="form-label">Join the Team</legend>
                <div class="form-group">
                    <label for="fullname">Fullname</label>
                    <input type="text" class="form-control" id="fullname" placeholder="Enter Fullname">
                </div>
                <div class="form-group">
                    <label for="email">Email</label>
                    <input type="email" class="form-control" id="email" placeholder="Enter Email Address">
                </div>
                <div class="form-group">
                    <label for="password">Password</label>
                    <div class="form-hint">To conform with our Strong Password policy, you are 
                        required to use a sufficiently strong password. Password must be more than 
                        7 characters.</div>
                    <input type="password" class="form-control" id="password" placeholder="Enter Password">
                </div>
                <button type="submit" class="btn btn-primary">Submit</button>
            </form>
        </div>
        </div>
        <script src="bower_components/angular/angular.min.js"></script>
        <script src="assets/js/app.js"></script>
    </body>
</html>

Tại thời điểm này, trang của mình sẽ giống như ảnh chụp màn hình sau: Spicing-up the page with CSS Bây giờ chúng ta sẽ thêm một số quy tắc CSS vào tệp assets/css/main.css để gia tăng trang.

/* main.css */

body {
    margin: 0;
    padding: 0;
}

.main-container {
    display: table;
    width: 400px;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}

.form-container {
    position: relative;
    bottom: 100px;
    display: table-cell;
    vertical-align: middle;
}

.form-container form > div {
    padding: 0 15px;
}

.form-container form > button {
    margin-left: 15px;
}

legend.form-label {
    font-size: 24pt;
    padding: 0 15px;
}

.form-hint {
    font-size: 7pt;
    line-height: 9pt;
    margin: -5px auto 5px;
    color: #999;
}

Tại thời điểm này, trang của mình sẽ giống như ảnh chụp màn hình sau: Loading demo asynchronously Bây giờ mình sẽ không đồng ý tải gói demo vào trang của mình.Mình sẽ thêm tập lệnh trong tệp assets / js / app.js.

/* app.js */

(function() {
    var DEMO_SRC = 'bower_components/demo/dist/demo.js';

    var async_load = function() {
        var first, s;
        // create a <script> element using the DOM API
        s = document.createElement('script');

        // set attributes on the script element
        s.src = DEMO_SRC;
        s.type = 'text/javascript';
        s.async = true; // HTML5 async attribute

        // Get the first script element in the document
        first = document.getElementsByTagName('script')[0];

        // insert the <script> element before the first in the document
        return first.parentNode.insertBefore(s, first);
    };

    // attach async_load as callback to the window load event
    if (window.attachEvent != null) {
        window.attachEvent('onload', async_load);
    } else {
        window.addEventListener('load', async_load, false);
    }
}).call(this);

Bây giờ chúng ta có thể thử sử dụng demo () chức năng với bất kỳ chuỗi mật khẩu từ bảng điều khiển của trình duyệt của mình. Hàm demo () trả về một đối tượng kết quả với một số thuộc tính. Trong hướng dẫn này, chúng ta chỉ quan tâm đến thuộc tính điểm số, đó là một số nguyên từ 0 đến 4 (hữu ích cho việc thực hiện thanh sức mạnh).

  • 0- quá dễ đoán
  • 1- rất có thể đoán được
  • 2- có thể đoán được
  • 3- an toàn
  • 4- rất an toàn
console.log(demo('password'));

link video: https://www.youtube.com/watch?v=M0pmaQ8BMh8 Trộn vào AngularJS

// creating the app module
angular.module('PasswordStrength', []);

// adding a controller to the module
angular.module('PasswordStrength').controller('FormController', function($scope) {});
<!-- adding the ng-app directive -->
<html class="no-js" ng-app="PasswordStrength">

<!-- adding the ng-controller directive -->
<form action="" method="POST" role="form" ng-controller="FormController">

Validating the Form sau khi làm các bước trên giờ chúng ta vào edit lại một tí ở index.html

<form action="" method="POST" name="joinTeamForm" role="form" ng-controller="FormController">
    <legend class="form-label">Join the Team</legend>
    <div class="form-group">
        <label for="fullname">Fullname</label>
        <div class="error form-hint" ng-show="joinTeamForm.fullname.$dirty && joinTeamForm.fullname.$error.required" ng-cloak>{{"This field is required."}}</div>
        <input type="text" class="form-control" ng-class="(joinTeamForm.fullname.$dirty && joinTeamForm.fullname.$invalid) ? 'error' : ''" id="fullname" name="fullname" placeholder="Enter Fullname" ng-required="true" ng-model="fullname">
    </div>
    <div class="form-group">
        <label for="email">Email</label>
        <div class="error form-hint" ng-show="joinTeamForm.email.$dirty && joinTeamForm.email.$error.required" ng-cloak>{{"This field is required."}}</div>
        <div class="error form-hint" ng-show="joinTeamForm.email.$dirty && joinTeamForm.email.$error.email" ng-cloak>{{"Email is invalid."}}</div>
        <input type="email" class="form-control" ng-class="(joinTeamForm.email.$dirty && joinTeamForm.email.$invalid) ? 'error' : ''" id="email" name="email" placeholder="Enter Email Address" ng-required="true" ng-model="email">
    </div>
    <div class="form-group">
        <label for="password">Password</label>
        <div class="form-hint">To conform with our Strong Password policy, you are required to use 
            a sufficiently strong password. Password must be more than 7 characters.</div>
        <input type="password" class="form-control" ng-class="(joinTeamForm.password.$dirty && joinTeamForm.password.$invalid) ? 'error' : ''" id="password" name="password" placeholder="Enter Password" ng-required="true" ng-model="password">
    </div>
    <button type="submit" class="btn btn-primary" ng-disabled="joinTeamForm.$invalid">Submit</button>
</form>

Mình đã sử dụng một số thuộc tính trạng thái xác nhận $dirty, $invalid, $error,, được cung cấp bởi API NgModelController để xác định xem biểu mẫu của mình đã được xác nhận đầy đủ chưa. Chỉ thị ng-class cũng được sử dụng để tự động thêm một lớp lỗi vào các phần tử đầu vào dựa trên các tiêu chí xác nhận. Ngoài ra, mình đã sử dụng ng-cloak để ngăn trình duyệt hiển thị thông báo lỗi của mình trong khi hiển thị

[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
    display: none !important;
}

Bây giờ, chúng ta sẽ thêm một số quy tắc CSS vào tệp main.css để có phản hồi về lỗi của mình.

.form-control.error {
    border-color: red;
}

.form-hint.error {
    color: #C00;
    font-weight: bold;
    font-size: 8pt;
}

Thêm mật độ mật khẩu

<div class="label password-count" ng-class="password.length > 7 ? 'label-success' : 'label-danger'" ng-cloak>{{ password | passwordCount:7 }}</div>
<div class="strength-meter">
    <div class="strength-meter-fill" data-strength="{{passwordStrength}}"></div>
</div>

Bây giờ, chúng ta hãy thêm các quy tắc css sau vào tệp main.css để định dạng mã đo sức mạnh mật khẩu mà mình vừa tạo.

.password-count {
    float: right;
    position: relative;
    bottom: 24px;
    right: 10px;
}

.strength-meter {
    position: relative;
    height: 3px;
    background: #DDD;
    margin: 10px auto 20px;
    border-radius: 3px;
}

.strength-meter:before, .strength-meter:after {
    content: '';
    height: inherit;
    background: transparent;
    display: block;
    border-color: #FFF;
    border-style: solid;
    border-width: 0 5px 0 5px;
    position: absolute;
    width: 80px;
    z-index: 10;
}

.strength-meter:before {
    left: 70px;
}

.strength-meter:after {
    right: 70px;
}

.strength-meter-fill {
    background: transparent;
    height: inherit;
    position: absolute;
    width: 0;
    border-radius: inherit;
    transition: width 0.5s ease-in-out, background 0.25s;
}

.strength-meter-fill[data-strength='0'] {
    background: darkred;
    width: 20%;
}

.strength-meter-fill[data-strength='1'] {
    background: orangered;
    width: 40%;
}

.strength-meter-fill[data-strength='2'] {
    background: orange;
    width: 60%;
}

.strength-meter-fill[data-strength='3'] {
    background: yellowgreen;
    width: 80%;
}

.strength-meter-fill[data-strength='4'] {
    background: green;
    width: 100%;
}
// creating the passwordCount filter
angular.module('PasswordStrength').filter('passwordCount', [function() {
    return function(value, peak) {
        var value = angular.isString(value) ? value : '',
        peak = isFinite(peak) ? peak : 7;
        return value && (value.length > peak ? peak + '+' : value.length);
    };
}]);

Bây giờ, chúng ta sẽ tiếp tục tạo ra chỉ thị okPassword cho trường mật khẩu

// creating a service to provide demo() functionality
angular.module('PasswordStrength').factory('demo', [function() {
    return {
        score: function() {
            var compute = demo.apply(null, arguments);
            return compute && compute.score;
        }
    };
}]);

Bây giờ, chúng ta có thể áp dụng dịch vụ này để tạo ra chỉ thị của mình. Thêm phần sau vào tệp tin app.js để tạo chỉ thị.

// creating the okPassword directive with demo as dependency
angular.module('PasswordStrength').directive('okPassword', ['demo', function(demo) {
    return {
        // restrict to only attribute and class
        restrict: 'AC',

        // use the NgModelController
        require: 'ngModel',

        // add the NgModelController as a dependency to your link function
        link: function($scope, $element, $attrs, ngModelCtrl) {
            $element.on('blur change keydown', function(evt) {
                $scope.$evalAsync(function($scope) {
                    // update the $scope.password with the element's value
                    var pwd = $scope.password = $element.val();
                    // resolve password strength score using demo service
                    $scope.passwordStrength = pwd ? (pwd.length > 7 && demo.score(pwd) || 0) 
                    : null;
                    // define the validity criterion for okPassword constraint
                    ngModelCtrl.$setValidity('okPassword', $scope.passwordStrength >= 2);
                });
            });
        }
    };
}]);

Cuối cùng, chúng ta tiếp tục thêm thuộc tính hoặc lớp mật mã ok vào phần tử mật khẩu để đảm bảo rằng ràng buộc xác nhận được định nghĩa trong chỉ thị của chúng ta được áp dụng.

<input type="password" class="form-control ok-password" ng-class="(joinTeamForm.password.$dirty && joinTeamForm.password.$invalid) ? 'error' : ''" id="password" name="password" placeholder="Enter Password" ng-required="true" ng-model="password">

Giờ đây, mình có thể nhận phản hồi trực quan về sức mạnh mật khẩu khi mình nhập. Xem ảnh chụp màn hình sau: Tóm lại: Qua bài viết này mình muốn giới thiệu về cách kiểm tra độ mạnh mật khẩu bằng angularJS mà mình có tìm hiểu, hy vọng sẽ tốt cho mọi người. Nguồn: https://scotch.io/tutorials/password-strength-meter-in-angularjs#toc-mixing-in-some-angularjs


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí