Sau đây là các bước để tích hợp xác thực vào ứng dụng sử dụng framework Sails.js. Trong bài viết này sử dụng cơ chế xác thực local (i.e tài khoản/mật khẩu người dùng lưu trên ứng dụng).

sails-passport

Step 1: Các gói phụ thuộc

Ứng dụng cần phụ thuộc các gói sau đây:

  • passport
  • passport-local
  • bcryptjs

Thêm vào app_dir/package.json vào mục dependencies:

//app_dir/package.json
{
...
  "dependencies": {
    ...
    "passport": "~0.2.1",
    "passport-local": "~1.0.0",
    "bcryptjs": "~2.1.0"
  }
...
}

Mở terminal, và cd tới thư mục dự án và chạy lệnh tải xuống các gói phụ thuộc:

npm install

Step 2: Tạo model User

Sử dụng lệnh sails để tạo model User:

sails generate model user

Giờ ứng dụng bạn có thêm 1 file mới được sinh ra tại: app_dir/api/models/User.js
Hãy thêm các trường thuộc tính phù hợp với ứng dụng của bạn và thêm cơ chế băm mật khẩu để tăng tính bảo mật cho người dùng như sau:

/**
 * User
 *
 * @module      :: Model
 * @description :: A short summary of how this model works and what it represents.
 *
 */
var bcrypt = require('bcryptjs');
 
module.exports = {
 
  attributes: {
    username: {
      type: 'string',
      required: true,
      unique: true
    },
    password: {
      type: 'string',
      required: true
    },
    toJSON: function() {
      var obj = this.toObject();
      delete obj.password;
      return obj;
    }
  },
 
  beforeCreate: function(user, cb) {
    bcrypt.genSalt(10, function(err, salt) {
      bcrypt.hash(user.password, salt, function(err, hash) {
        if (err) {
          console.log(err);
          cb(err);
        }else{
          user.password = hash;
          cb(null, user);
        }
      });
    });
  }
 
};

Step 3: Tạo AuthController và view đăng nhập, đăng ký

Tạo Auth controller, như sau:

sails generate controlller Auth

Sửa AuthController vừa sinh ra tại app_dir/controllers/AuthController.js và thêm các Action: login, logout

Giờ AuthController sẽ trông dư thế này:

/**
 * AuthController
 *
 */
var passport = require('passport');

module.exports = {

    _config: {
        actions: false,
        shortcuts: false,
        rest: false
    },

    login: function(req, res) {

        passport.authenticate('local', function(err, user, info) {
            if ((err) || (!user)) {
                return res.send({
                    message: info.message,
                    user: user
                });
            }
            req.logIn(user, function(err) {
                if (err) res.send(err);
                return res.send({
                    message: info.message,
                    user: user
                });
            });

        })(req, res);
    },

    logout: function(req, res) {
        req.logout();
        res.redirect('/');
    }
};

Tạo Login view

Tạo 1 file template tại: app_dir/views/auth/login.ejs có nội dung như sau:

<form action="/login" method="post">
    <div><input name="username" type="text"></div>
    <div><input name="password" type="password"></div>
    <div><input type="submit"></div>
</form>

Tạo Signup view

Tạo 1 file template tại: app_dir/views/auth/signup.ejs có nội dung như sau:

<form action="/user" method="post">
    <div><input name="username" type="text"></div>
    <div><input name="password" type="password"></div>
    <div><input type="submit"></div>
</form>

Step 4: Cấu hình route

Tiếp tục ta cấu hình route để mapping các action, view tương ứng với các request tới server.

Mở file app_dir/config/routes.js và cấu hình route như sau:

module.exports.routes = {
  '/': {
    view: 'homepage'
  },

  'get /login': {
       view: 'login'
  },

  'post /login': 'AuthController.login',

  '/logout': 'AuthController.logout',

  'get /signup': {
    view: 'signup'
  }
}

Step 5: Cấu hình passport như 1 Express middleware

Bạn cần tùy chỉnh và cấu hình Passport trong file app_dir/config/http.js như sau:

module.exports.http = {
   middleware: {

    passportInit    : require('passport').initialize(),
    passportSession : require('passport').session(),

     order: [
            'startRequestTimer',
            'cookieParser',
            'session',
            'passportInit',     
            'passportSession', 
            'myRequestLogger',
            'bodyParser',
            'handleBodyParserError',
            'compress',
            'methodOverride',
            'poweredBy',
            'router',
            'www',
            'favicon',
            '404',
            '500'
          ],
     }
};

Theo thứ tự chúng ta đã add passportInitpassportSession sau middleware session. Tên các phần tử trong mảng này thể hiện chức năng của nó và chúng ta cần sắp xếp như thứ tự trên để ứng dụng có thể hoạt động đúng.

Step 6: Thiết kế chiến lược xác thực passport local

Cơ bản trong bước này là chúng ta sẽ gọi hàm xác thực passport với các thông tin người dùng gửi lên khi họ click nút submit_login.

Tạo file app_dir/config/passport.js và thêm nội dung như sau:

var passport = require('passport'),
  LocalStrategy = require('passport-local').Strategy,
  bcrypt = require('bcryptjs');

passport.serializeUser(function(user, done) {
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  User.findOne({ id: id } , function (err, user) {
    done(err, user);
  });
});

passport.use(new LocalStrategy({
    usernameField: 'username',
    passwordField: 'password'
  },
  function(username, password, done) {

    User.findOne({ username: username }, function (err, user) {
      if (err) { return done(err); }
      if (!user) {
        return done(null, false, { message: 'Incorrect email.' });
      }

      bcrypt.compare(password, user.password, function (err, res) {
        if (!res)
          return done(null, false, {
            message: 'Invalid Password'
          });
        var returnUser = {
          username: user.username,
          createdAt: user.createdAt,
          id: user.id
        };
        return done(null, returnUser, {
          message: 'Logged In Successfully'
        });
      });
    });
  }
));

Step 7: Cập nhật policy

Tạo mới hoặc cập nhật file app_dir/api/policies/isAuthenticated.js với nội dung như sau:

module.exports = function(req, res, next) {
   if (req.isAuthenticated()) {
        return next();
    }
    else{
        return res.redirect('/login');
    }
};

Việc làm tại bước này có nghĩa là, buộc tất cả người dùng phải được xác thực trước khi truy cập trang. Khác thì điều hướng họ về trang /login. Nhưng chúng ta cần thiết lập các chính sách policies tới các controllers.

Step 8: Gán policy vào controller

Giờ ta giả sử hệ thống có 1 trang quản trị và được điều khiển bởi AdminController và chỉ có user đã thực hiện đăng nhập thành công vào hệ thống mới được phép truy cập.

Nội dung của AdminController:

sails generate controller Admin
module.exports = {
  index: function (req, res) {
    res.send('This is your admin page');
  }
};

Cập nhật file app_dir/config/routes.js thêm route tới trang admin

module.exports.routes = {
  '/': {
    view: 'homepage'
  },

  'get /myadmin': 'AdminController.index',

  'get /login': {
       view: 'login'
  },

  'post /login': 'AuthController.login',

  '/logout': 'AuthController.logout',

  'get /signup': {
    view: 'signup'
  }
}

Và cập nhật nội dung file app_dir/config/policies.js như sau:

module.exports.policies = {

   '*': true,

  'AdminController': {
    '*': 'isAuthenticated'
  },

};

Step 9: Test

Chạy ứng dụng bằng lệnh:

npm install 
sails lift

1. Truy cập thử http://localhost:1337/myadmin – lần đầu chắc chắn bạn sẽ bị redirect tới trang login.

2. Vào trang http://localhost:1337/signup đăng ký lấy 1 cái tài khoản

3. Vào trang http://localhost:1337/login đăng nhập với toàn khoản vừa đăng ký.

4. Truy cập trang admin http://localhost:1337/myadmin và bạn sẽ thấy dòng text xuất hiện This is your admin page

5. Truy cập trang http://localhost:1337/logout để đăng xuất

Trên đây là các bước cơ bản hướng dẫn bạn tích hợp xác thực người dùng vào trong ứng dụng Sails.js của bạn.

Chúc bạn thành công !

Liên kết tham khảo

About The Author