Hướng dẫn sử dụng JSON web token để xác thực trong Sails.js

Trong bài viết này, mình sẽ hướng dẫn các bạn sử dụng JSON web token trong Sails.js. Chúng ta sẽ làm môt ví dụ đơn giản nhất với username và password cho user sign-up/in. Đầu tiên bạn run npm i jsonwebtoken bcrypt --save trước khi bắt đâu bài hướng dẫn này.

Đầu tiên, bạn cần tạo service “jwToken”.

Bạn vào folder api/services để tạo file jwToken.js

/**
* jwToken
*
* @description :: JSON Webtoken Service for sails
* @help :: See https://github.com/auth0/node-jsonwebtoken & http://sailsjs.org/#!/documentation/concepts/Services
*/

var
jwt = require('jsonwebtoken'),
tokenSecret = "secretissecet"


module.exports.issue = function(payload) {
	return jwt.sign(
	payload,
	tokenSecret,
	{
		expiresInMinutes : 180 // Thời gian sống của token
	});
};

// Xác thực token từ request
module.exports.verify = function(token, callback) {
	return jwt.verify(
		token, // Token đã xác thực
		tokenSecret, // Same token we used to sign
		{}, // No Option,Xem thêm: https://github.com/auth0/node-jsonwebtoken#jwtverifytoken-secretorpublickey-options-callback
		callback //Pass errors or decoded token to callback
	);
};

Tiếp theo, bạn vào folder api/models để tạo file Users.js

/**
* Users.js
*
* @description :: TODO: You might write a short summary of how this model works and what it represents here.
* @docs :: http://sailsjs.org/#!documentation/models
*/

// Chúng ta sẽ không cần lưu mật khẩu 
var bcrypt = require('bcrypt');

module.exports = {

schema: true,

attributes: {
	email: {
	type: 'email',
	required: 'true',
	unique: true // Yes unique one
},

encryptedPassword: {
type: 'string'
},

toJSON: function () {
var obj = this.toObject();
delete obj.encryptedPassword;
return obj;
}
},
// Mã hóa password trước khi tạo User
beforeCreate : function (values, next) {
	bcrypt.genSalt(10, function (err, salt) {
	if(err) return next(err);
		bcrypt.hash(values.password, salt, function (err, hash) {
		if(err) return next(err);
			values.encryptedPassword = hash;
			next();
		})
	})
},

	comparePassword : function (password, user, cb) {
		bcrypt.compare(password, user.encryptedPassword, function (err, match) {

		if(err) cb(err);
			if(match) {
				cb(null, true);
			} else {
				cb(err);
			}
		})
	}
};

Bước tiếp theo, chúng ta override “create” action cho user sign-up
api/controllers/UsersController.js:

/**
* UsersController
*
* @description :: Server-side logic for managing users
* @help :: See http://links.sailsjs.org/docs/controllers
*/

module.exports = {
	create: function (req, res) {
		if (req.body.password !== req.body.confirmPassword) {
			return res.json(401, {err: 'Password doesn\'t match, What a shame!'});
		}
		Users.create(req.body).exec(function (err, user) {
			if (err) {
				return res.json(err.status, {err: err});
			}
			// Nếu tạo user thành công sẽ return user và token
			if (user) {
				// NOTE: payload is { id: user.id}
				res.json(200, {user: user, token: jwToken.issue({id: user.id})});
			}
		});
	}
};

Bây giờ, chúng ta cần một cần tạo một controller api/controllers/AuthController.js cho users

/**
* AuthController
*
* @description :: Server-side logic for managing auths
* @help :: See http://links.sailsjs.org/docs/controllers
*/

module.exports = {
	index: function (req, res) {
		var email = req.param('email');
		var password = req.param('password');

		if (!email || !password) {
			return res.json(401, {err: 'email and password required'});
		}

		Users.findOne({email: email}, function (err, user) {
			if (!user) {
				return res.json(401, {err: 'invalid email or password'});
			}

			Users.comparePassword(password, user, function (err, valid) {
				if (err) {
				return res.json(403, {err: 'forbidden'});
					}

				if (!valid) {
					return res.json(401, {err: 'invalid email or password'});
				} else {
					res.json({
					user: user,
					token: jwToken.issue({id : user.id })
					});
				}
			});
		})
	}
};

Bây giờ, chúng ta sẽ tạo 1 isAuthorized policy để kiểm tra các request không có token. Vào folder api/policies/ tạo file isAuthorized.js:

/**
* isAuthorized
*
* @description :: Policy to check if user is authorized with JSON web token
* @help :: See http://sailsjs.org/#!/documentation/concepts/Policies
*/

module.exports = function (req, res, next) {
	var token;

	if (req.headers && req.headers.authorization) {
		var parts = req.headers.authorization.split(' ');
		if (parts.length == 2) {
			var scheme = parts[0],
			credentials = parts[1];

			if (/^Bearer$/i.test(scheme)) {
				token = credentials;
			}
		} else {
			return res.json(401, {err: 'Format is Authorization: Bearer [token]'});
		}
	} else if (req.param('token')) {
			token = req.param('token');
			// We delete the token from param to not mess with blueprints
			delete req.query.token;
		} else {
			return res.json(401, {err: 'No Authorization header was found'});
		}

	jwToken.verify(token, function (err, token) {
	if (err) return res.json(401, {err: 'Invalid Token!'});
		req.token = token; // This is the decrypted token or the payload you provided
		next();
	});
};

Sau đó chúng ta vào folder config/policies.js để bảo về controllers của chúng ta

/*
* For more information on how policies work, see:
* http://sailsjs.org/#/documentation/concepts/Policies
*
* For more information on configuring policies, check out:
* http://sailsjs.org/#/documentation/reference/sails.config/sails.config.policies.html
*/

module.exports.policies = {

	'*': ['isAuthorized'], // Tất cả sẽ bị chặn ở đây
		'UsersController': {
		'create': true // Chúng ta không cần xác thực tại đây
	},

	'AuthController': {
		'*': true // Chúng ta không cần xác thực tại đây
	}
};

Bây giờ chúng ta cùng test. Khởi động lại server sails lift và test với Postman
Gửi request với phương thức GET đến /users:

{
"err": "No Authorization header was found"
}

Bây giờ , chúng ta cần gửi một request với phương thức POST để tạo user users/ với email,passworda và confirmPassword:

{
"user": {
"email": "email@mail.mail",
"createdAt": "2015-04-26T10:02:15.774Z",
"updatedAt": "2015-04-26T10:02:15.774Z",
"id": 2
},
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MiwiaWF0IjoxNDMwMDQyNTM1LCJleHAiOjE0MzAwNTMzMzV9.rDr89JFZtZnTq4Zv8T2ZET0FgVy59ezRYLWXw75VnF0"
}

Chúng ta đã được token
Bây giờ, bạn thử gửi lại request đến /users với token bạn vừa nhận được để xem kết quả nhé.

[
	{
		"email": "email@mail.mail",
		"createdAt": "2015-04-26T10:02:15.774Z",
		"updatedAt": "2015-04-26T10:02:15.774Z",
		"id": 1
    }
]

Nguồn : How to use json token authentication with sails js


Leave a Reply

Your email address will not be published. Required fields are marked *

×