ພັດທະນາ Web Application ໃຫ້ support 2FA Authentication ດ້ວຍ speakeasy

xangnam phiasakha
VtCamp
Published in
5 min readDec 31, 2018

ສະບາຍດີ.! ນັກພັດທະນາທຸກຄົນບົດຄວາມນີ້ເປັນບົດຄວາມສຸດທ້າຍຂອງປີ 2018 ສຳລັບຜູ້ຂຽນເອງ ແລະ ປີ 2019 ຈຶ່ງພົບກັນໃໝ່ກັບບົດຄວາມດີໆຈາກກຸ່ມຂອງພວກເຮົາ.

ໃນໄລຍະຜ່ານມາເລື່ອງຂອງ security ເຂົາມີບົດບາດຫຼາຍໃນວົງການ Tecnology ຄວາມຈິງກໍ່ມີບົດບາດມາດົນແລ້ວແຕ່ມັນໄດ້ເປັນໄພກັບທຸກຄົນບໍ່ສະເພາະແຕ່ອົງກອນ ຫຼື ບໍລິສັດເທົ່ານັ້ນ. ເພາະເນື່ອງມາຈາກ Social Media ທີ່ເຂົ້າມາມີບົດບາດຫຼາຍຂຶ້ນກັບສັງຄົມມະນຸດປະຈຸບັນ ແລະ ທຸກຄົນກໍ່ສາມາດເຂົ້າເຖິງ Internet ໄດ້ທຸກຄົນ. ດັ່ງນັ້ນບໍລິການສື່ດັງຕ່າງໆຈຶ່ງຫາກົນລະຍຸດວິທີທາງຕ່າງໆໃນການຮັກສາຄວາມປອດໄພໃຫ້ກັບລູກຄ້າ ຫຼື ຜູ້ໃຊ້ເຊິ່ງໜຶ່ງໃນວິທີທີ່ໄດ້ຮັບຄວາມນິຍົມ ແລະ ເຫັນມີການໃຊ້ແພ່ຫຼາຍໃນປັດຈຸບັນກໍ່ຄື Two-Factor Authentication.

Two-Factor Authentication(2FA)

2FA ຄື One-time passcode ທີ່ຈະເປັນຕົວເລກທີ່ໃຊ້ໄດ້ພຽງຄັ້ງດຽວໃນການຢືນຢັນການເຂົ້າສູ່ລະບົບ. ເປັນວິທີ ທີ່ໃຫ້ຜູ້ໃຊ້ຫຼັງຈາກ login ດ້ວຍ User ແລະ Password ແບບປົກກະຕິແລ້ວກໍ່ຕ້ອງໄດ້ໃຊ້ 2FA Token ອີກຄັ້ງເພື່ອເຂົ້າສູ່ລະບົບເຊິ່ງ 2FA Token ນີ້ມີດ້ວຍກັນສອງປະເພດຄື: HMAC-Based One-Time Password (HOTP) ແລະ Time-Based One-time Password (TOTP) ສຳລັບ HOTP Token ຈະເປັນຕົວເລກ 6 ໂຕທີ່ຈະປ່ຽນທຸກຄັ້ງຕາມ counter ຫຼື ຕົວນັບ. ສ່ວນ TOTP Token ກໍ່ຈະເປັນຕົວເລກ 6 ຕົວເຊັ່ນກັນແຕ່ປ່ຽນແປງຕາມເວລາ ໂດຍຈະປ່ຽນທຸກໆ 30 sec ໂດຍມາດຕະຖານ. ສະນັ້ນເມື່ອມີຄົນສາມາດ login ດ້ວຍ User ແລະ Password ຂອງເຮົາແລ້ວຕ້ອງມີ 2FA Token ອີກຈຶ່ງຈະສາມາດເຂົ້າໃຊ້ງານໄດ້ເຊິ່ງການທີ່ຈະເດົາ ຫຼື ໃຊ້ການ Blue-Force ກໍ່ຕາມເປັນໄປໄດ້ຍາກທີ່ຈະສຳເລັດເພາະ 2FA ຈະປ່ຽນແປງໄປຕະຫຼອດ (ແຕ່ບໍ່ໄດ້ໝາຍຄວາມວ່າຈະ bypass ບໍ່ໄດ້)

https://www.howtogeek.com/199262/authy-two-factor-authentication-made-easy/

ການເຮັດວຽກຂອງ 2FA ລະດັບ High Level

2FA ຈະມີສອງປະເພດຄື: HOTP ແລະ TOTP ເຊິ່ງ HOTP ຈະຖືກກຳນົດໂດຍມາດຕະຖານ RFC 4226 ແລະ TOTP ຈະກຳນົດດ້ວຍມາດຕະຖານ RFC 6238 ເຊິ່ງວິທີທັງສອງຈະມີການ generate secret ໃຫ້ຜູ້ໃຊ້ ແລະ ຄຳນວນ 2FA Token ເປັນຕົວເລກ 6 ໂຕທີ່ຜູ້ພັດທະນາອາດຈະໃຊ້ວິທີການສົ່ງໃຫ້ຜູ້ໃຊ້ຜ່ານ Email, SMS ຫຼື ຜູ້ໃຊ້ອາດເກັບໄວ້ເອງໂດຍໃຊ້ Hardware tokens, Google Authenticator , Authy Application ເປັນຕົ້ນ. ຫຼັງຈາກທີ່ຜູ້ໃຊ້ login ດ້ວຍວິທີປົກກະຕິແລ້ວກໍ່ເອົາ 2FA Token ທີ່ໄດ້ມານັ້ນມາຢືນຢັນອີກຈຶ່ງຈະສາມາດເຂົ້າໃຊ້ງານລະບົບໄດ້.

Flow ການ Enable ແລະ Login ດ້ວຍ 2FA

ເມື່ອເຮົາຕ້ອງການນຳເອົາ 2FA ເຂົ້າມາໃຊ້ກັບລະບົບ Authentication ຂອງ Web Application ຫຼື Mobile Application ກໍ່ຕາມສິ່ງທີ່ຕ້ອງຮູ້ຄື Flow ການໃຊ້ງານ 2FA. ເຊິ່ງການທີ່ຈະໃຊ້ງານ 2FA ນັ້ນເລີ່ມຕົ້ນແມ່ນໃຫ້ຜູ້ໃຊ້ login ດ້ວຍ User ແລະ Password ປົກກະຕິ ຫຼັງຈາກນັ້ນກໍ່ໃຫ້ຜູ້ໃຊ້ເປີດການໃຊ້ງານ 2FA ຫຼັງຈາກເປີດໃຊ້ງານແລ້ວເມື່ອມີການ login ເຂົ້າມາໃຊ້ໃໝ່ກໍ່ເປັນຂັ້ນຕອນການຢືນຢັນການເຂົ້າສູ່ລະບົບໂດຍການນຳເອົາ 2FA Token ນັ້ນມາໃສ່ຈຶ່ງຈະສາມາດເຂົ້າໃຊ້ງານລະບົບໄດ້.

credit : https://ciphertrick.com/2017/09/19/two-factor-authentication-nodejs-stateless-application/

Implement 2FA Authentication ດ້ວຍ speakeasy

speakeasy ເປັນ One-time passcode generator(2FA) library ສຳລັບ nodejs ທີ່ຈະຊ່ວຍໃຫ້ການ implement 2FA ນັ້ນງ່າຍຂຶ້ນເປັນເທົ່າໂຕເຊິ່ງ support HMAC-Based One-Time Password (HOTP) algorithm ແລະ Time-Based One-time Password (TOTP) algorithm

ໃນການສະແດງໃຫ້ເຫັນການໃຊ້ງານ 2FA ຜູ້ຂຽນໄດ້ສ້າງ project ຕົວຢ່າງຂຶ້ນມາເຊິ່ງມີ flow ດັ່ງນີ້

Enable 2FA

web application ແບບໂຄດຂີ້ຄ້ານເຮັດ

Login with 2FA

web application ແບບໂຄດຂີ້ຄ້ານເຮັດ

ສຳລັບຕົວຢ່າງການໃຊ້ງານ speakeasy ເພື່ອສ້າງ 2FA Authentication ນັ້ນຜູ້ຂຽນຈະແບ່ງອອກເປັນສອງສ່ວນຄື: ຕົວຢ່າງສຳລັບ TOTP ແລະ HOTP.

ຕົວຢ່າງການໃຊ້ງານ 2FA ແບບ TOTP

TOTP ຈະເປັນວິທີທີ່ໄດ້ຮັບຄວາມນິຍົມ ແລະ ໃຊ້ກັນແພ່ຫຼາຍເນື່ອງມາຈາກການທີ່ Token ຈະຖືກ refresh ຕາມເວລາທຸກໆ 30 sec ສະນັ້ນການນຳໄປໃຊ້ງານຈະງ່າຍກວ່າ HOTP.

ໃນການສ້າງ project ນັ້ນ ຈະບໍ່ເວົ້າຫຼາຍໃນສ່ວນນີ້ແຕ່ຈະເນັ້ນໄປທີ່ການໃຊ້ງານ speakeasy ເປັນຫຼັກໂດຍໃນການພັດທະນາເວັບຕົວຢ່າງນີ້ຜູ້ຂຽນໃຊ້ Expressjs ສ່ວນວິທີໃຊ້ງານກໍ່ໄປສຶກສາກັນເອງໄດ້ເລີຍ.

ກັບມາທີ່ application ຕົວຢ່າງຂອງເຮົາ. ຜູ້ຂຽນຈະຈຳລອງການເກັບຂໍ້ມູນຢູ່ຖານຂໍ້ມູນໂດຍເກັບລົງ file json ທຳມະດານີ້ຫລ່ະ!. ຮູບຮ່າງໜ້າຕາຂອງຂໍ້ມູນທີ່ເກັບຢູ່ໃນ file ກໍ່ຈະປະມານນີ້

ເຊິ່ງສ່ວນ auth ຈະເກັບ user ແລະ password , ສ່ວນ two_factor_auth ເກັບສະຖານະບອກວ່າ user ຜ່ານການ enable 2FA ແລ້ວຫຼືຍັງ ແລະ secret key ຂອງ 2FA.

ວ່າແລ້ວກໍ່ເລີ່ມຕິດຕັ້ງ speakeasy ກັນເລີຍ

$ yarn add speakeasy

ມີ 3 ຂັ້ນຕອນທີ່ເຮົາຈະຕ້ອງເຮັດໃນການໃຊ້ງານ speakeasy

  1. Generate a secret
  2. ສະແດງ QRCode ໃຫ້ຜູ້ໃຊ້ scan ດ້ວຍ 2FA Application ເຊັ່ນ: Google Authenticator , Authy
  3. Authenticate the token ສຳລັບເລີ່ມຕົ້ນໃຊ້ງານ 2FA ຄັ້ງທຳອິດ(ເປີດໃຊ້ງານ)

Generate a secret

const secret = speakeasy.generateSecret({name: "xangnam two-factor"});

ເຊິ່ງຈະໄດ້ key ທີ່ມີ length 32 ຫຼັງຈາກນັ້ນກໍ່ຕ້ອງເກັບມັນໄວ້ເປັນ temp secret key ໃນ encode ຮູບແບບ base32

json_data['two_factor_auth']['two_factor_auth_secret_temp'] = secret.base32

ເພື່ອລໍຖ້າການ confirm 2FA token ຈາກຜູ້ໃຊ້ເສຍກ່ອນ. ຈຶ່ງນຳໄປເກັບໄວ້ເປັນ secret key ທີ່ຈະນຳໄປໃຊ້ທຸກ Authentication.

ສະແດງ QRCode

ໃນການສະແດງ QRCode ໃຫ້ 2FA Application Scan ນັ້ນ ຈະໃຊ້ protocol otpauth:// ເຊິ່ງຖືກຕຽມໄວ້ໃຫ້ແລ້ວດ້ວຍ secret.otpauth_url

QRCode ທີ່ໄດ້ມາຈາກ code ຂ້າງເທິງ

ຫຼັງຈາກນັ້ນກໍ່ໃຊ້ 2FA Application scan ກໍ່ຈະໄດ້ຜົນຮັບປະມານນີ້

Verifying the token

ຫຼັງຈາກ scan QRCode ແລ້ວ ກໍ່ເປັນຂັ້ນຕອນຂອງການ verify 2FA token ທີ່ຜູ້ໃຊ້ໄດ້ມາຈາກ 2FA application

ເຊິ່ງເຮົາຈະໃຊ້ speakeasy.totp.verify({…}) ໃນການ verify token ທີ່ຜູ້ໃຊ້ສົ່ງເຂົ້າມາຖ້າຫາກຖືກຕ້ອງກໍ່ຈະ retrun ຄ່າເປັນ true ຖ້າບໍ່ກໍ່ຈະ retrun ຄ່ເປັນ fale. ໃນ option ທີ່ສຳຄັນຂອງ function verify ນີ້ແມ່ນຄ່າຂອງ window ທີ່ຈະເປັນຕົວກຳນົດອາຍຸການໃຊ້ງານຂອງ token ນັ້ນເພາະ totp token ຈະຖືກ generate ທຸກໆ 30 sec ຜູ້ໃຊ້ຕ້ອງສົ່ງມາໃນຂອບເຂດເວລານີ້ເຊິ່ງມັນເຮັດໃຫ້ UX ຂອງ Application ຂອງເຮົາບໍ່ດີຖ້າເປັນແບບນັ້ນ(ອາຍຸການໃຊ້ງານ token ໝົດໄວເກີນໄປ). ດັ່ງນັ້ນ ຈຶ່ງກຳນົດໃຫ້ Token ກ່ອນໜ້ານີ້ສາມາດໃຊ້ງານໄດ້ແຕ່ກໍ່ມີເວລາກຳນົດການໃຊ້ງານຂຶ້ນກັບຄ່າຂອງ window ທີ່ເຮົາກຳນົດນັ້ນເອງເພາະມັນເປັນຕົວກຳນົດຄ່າຄວາມແຕກຕ່າງລະຫວ່າງເວລາປະຈຸບັນ ແລະ ເວລາທີ່ token ຖືກ generate ຂຶ້ນມາ. ເຊິ່ງຄ່າຄວາມແຕກຕ່າງຂອງເວລານີ້ເອີ້ນວ່າ delta ທີ່ມີ function ໃນການຄຳນວນຄື totp․verifyDelta(options)

ຕົວຢ່າງການຫາຄ່າ delta

var token = speakeasy.totp.verifyDelta({
secret: secret.base32,
token: '123456',
window: 10
});
//token=> 5

ເຮົາສາມາດໃຊ້ຄ່າ delta ກວດສອບວ່າ token ທີ່ຜູ້ໃຊ້ສົ່ງມານັ້ນຖືກຕ້ອງຫຼືບໍ່ ໂດຍທີ່ function ນີ້ຈະຄືນຄ່າຄວາມແຕກຕ່າງ ຫຼື ຄວາມຫ່າງລະຫວ່າງເວລາຂອງ token ແລະ secret key ທີ່ຜູ້ໃຊ້ໄດ້ Scan ໄປກ່ອນໜ້ານີ້. ເຊິ່ງວ່າສາມາດມີຄ່າເປັນລົບຫຼືບວກກໍ່ໄດ້ເມື່ອ Token ນັ້ນຖືກຕ້ອງ. ສ່ວນ Token ທີ່ສົ່ງມາບໍ່ຖືກຕ້ອງຈະໃຫ້ຄ່າເປັນ undefine.
ແຕ່ຖ້າໃຊ້ function speakeasy.totp.verify({…}) ກໍ່ເປັນອັນວ່າບໍ່ຕ້ອງມາຂຽນກວດສອບຄ່າ delta ເອງ. ຫຼັງຈາກທີ່ Token ທີ່ຜູ້ໃຊ້ສົ່ງມາຖືກຕ້ອງຂັ້ນຕອນຕໍ່ໄປຄືການເກັບ secret key ທີ່ເຮົາເກັບໄວເປັນ key ຊົວຄາວນັ້ນປ່ຽນມາເກັບແບບຖ້າວອນພ້ອມທັງກຳນົດວ່າຜູ້ໃຊ້ຜ່ານການ Enable 2FA ເປັນທີ່ຮຽບຮ້ອຍແບບ. ເມື່ອຜູ້ໃຊ້ກັບມາ login ເຂົ້າສູ່ລະບົບໃໝ່ກໍ່ໃຫ້ສະແດງແຕ່ໜ້າທີ່ໃຫ້ໃສ່ 2FA Token ເທົ່ານັ້ນ.

ສຳລັບຕົວຢ່າງການໃຊ້ 2FA ແບບ TOTP ກໍ່ມີພຽງເທົ່ານີ້ຫລ່ະ!. ງ່າຍໆບໍ່ມີຫຍັງສັບຊ້ອນ.

ຕົວຢ່າງການໃຊ້ງານ 2FA ແບບ HOTP

HOTP ຈະເປັນວິທີເກົ່າໃນການເຮັດ 2FA ເຊິ່ງອາໄສການ refresh token ຈາກການເພີ່ມຄ່າໃຫ້ຕົວນັບຈາກການກົດເພື່ອ refresh token ຂອງຜູ້ໃຊ້ເອງເຊິ່ງວິທີນີ້ທັງ server ແລະ client ຕ້ອງມີການເກັບ counter ການກົດຂອງຜູ້ໃຊ້ເອົາໄວ້. ເວົ້າສະເພາະ server ຈະຕ້ອງເພີ່ມຄ່າ counter ທຸກໆການ login ຜ່ານ 2FA ທີ່ສຳເລັດ. ຫຼັງຈາກນັ້ນກໍ່ເກັບ counter ລົງຖານຂໍ້ມູນເພື່ອໃຊ້ໃນການ verify Token ທີ່ generate ໂດຍ 2FA Client.

ສຳລັບຕົວຢ່າງການໃຊ້ 2FA ແບບ HOTP ນັ້ນກໍ່ຈະຄ້າຍໆຄື TOTP ແຕ່ຈະຕ່າງບ່ອນວ່າຈະມີ counter ເຂົ້າມາກ່ຽວຂອງ ແລະ ການໄດ້ມາຂອງ otpauth_url ກໍ່ຈະແຕກຕ່າງຈາກ totp ເນື່ອງຈາກໂດຍ default ແລ້ວ secret.otpauth_url ຈະເປັນຮູບແບບ totp ໃນການສ້າງ QRCode ສຳລັບ HOTP ເຮົາຈະໃຊ້ otpauthURL(options) ສ້າງ string url ແທນ secret.otpauth_url.

ກ່ອນອື່ນເຮົາຕ້ອງສ້າງຮູບແບບການເກັບຂໍ້ມູນການ login ສະເພາະຂອງ HOTP ເຊິ່ງຮູບແບບກໍ່ຈະຄ້າຍໆຄືກັບ totp ແຕ່ຈະມີການເກັບ counter ເຂົ້າມາເພີ່ມ.

ສ່ວນສຳຄັນແມ່ນ counter ທີ່ເປັນການກຳນົດຈຸດເລີ່ມຕົ້ນຂອງການນັບແຕ່ວ່າ google authenticator support ການນັບເລີ່ມຈາກ 0 ສະນັ້ນຄ່າເລີ່ມຕົ້ນຂອງ counter ຈະເກັບເປັນ 0

Generate a secret

ຂັ້ນຕອນຈະບໍ່ຕ່າງຫຍັງຈາກ TOTP

const secret = speakeasy.generateSecret({name: "xangnam two-factor"});

ສະແດງ QRCode

ການສ້າງ QRCode ຈະໃຊ້ speakeasy.otpauthURL(option) ໃນການ generate string url ຂຶ້ນມາ. code ກໍ່ຈະປະມານນີ້

QRCode ທີ່ໃຫ້ 2FA Client Scan

ຫຼັງຈາກ scan ແລ້ວກໍ່ຈະໄດ້ດັງຮູບລຸ່ມນີ້ທີ່ຈະໃຫ້ເຮົາກົດເພື່ອ refresh Token ທຸກໆ 30 sec

Verifying the token

ໃນຂັ້ນຕອນ verify ກໍ່ບໍ່ໄດ້ຕ່າງຫຍັງຫຼາຍຈາກ totp

ເນື່ອງຈາກເມື່ອເຮົາກົດຄັ້ງໜຶ່ງຢູ່ 2FA Client ເປັນການບວກ counter ຂຶ້ນໄປອີກ 1 ສະນັ້ນເມື່ອອ່ານຄ່າ counter ທີ່ເກັບຢູ່ໃນຖານຂໍ້ມູນແລ້ວກໍ່ໃຫ້ບວກເພີ່ມໄປອີກ 1 ນອກນັ້ນຈະສັງເກດເຫັນ window option ທີ່ເປັນການ verify token ລວງໜ້າໃນກໍລະນີທີຜູ້ໃຊ້ກົດ refresh counter ຫຼາຍໆເທື່ອ.

ເມື່ອ verify ຜ່ານແລ້ວກໍ່ຄວນເກັບຄ່າ counter ທີ່ບວກຂຶ້ນມານັ້ນລົງຖານຂໍ້ມູນເພື່ອໃຊ້ໃນການ verify ໃນຄັ້ງຕໍ່ໆໄປ.

ຈະສັງເກດເຫັນວ່າວິທີຂອງ HOTP ຈະຍາກບ່ອນການບໍລິຫານຈັດການກັບ counter ເຊິ່ງຕ່າງຈາກ TOTP ທີ່ຈະໃຊ້ເວລາໃນການ refresh token.

ສະຫຼຸບ

ມາຮອດຈຸດນີ້ກໍ່ສະແດງວ່າຜູ້ອ່ານສາມາດນຳໃຊ້ 2FA Authentication ໃຫ້ກັບ Application ຂອງໂຕເອງໄດ້ແລ້ວ!. ການເລືອກໃຊ້ວິທີການ authentication ແບບໃດກໍ່ຕາມກໍ່ຂຶ້ນກັບວຽກ ແລະ ຄວາມເໝາະສົມຂອງວຽກແຕ່ຜູ້ຂຽນວ່າໃຊ້ TOTP ໄປເລີຍກໍ່ດີເພາະເຮົາບໍ່ຕ້ອງມາຫຍຸງຍາກກັບການເກັບ counter ຄື HOTP.

ສຳລັບ code ຂອງ project ຕົວຢ່າງນີ້ສາມາດໄປສຶກສາໄດ້ທີ່

ສຶກສາເພີ່ມເຕື່ມໄດ້ທີ່

ມາຮອດນີ້ ບົດຄວາມນີ້ກໍ່ເປັນອັນຈົບ ແລະ ອວຍພອນໃຫ້ທຸກຄົນໂຊກດີປີໃໝ່ 2019 ກັນທຸກຄົນ, ຂໍ້ໃຫ້ code ບໍ່ມີ bug ແລ້ວເຈີກັນກັບບົດຄວາມໃໝ່ໆໃນປີ 2019.

--

--