• About
  • Advertise
  • Privacy & Policy
  • Contact
DevZone
  • Home
  • News
  • Dev
    • All
    • Algorithm
    • Architecture
    • Database
    • Design
    • DevOps
    • IoT
    • Network
    • Test
    • Web
    Phương thức xử lý mảng trong javascript

    Phương thức xử lý mảng trong javascript

    Bảo vệ content, chống copy nội dung web!

    Bảo vệ content, chống copy nội dung web!

    Lưu ý mệnh đề NOT IN trong SQL

    Lưu ý mệnh đề NOT IN trong SQL

    SOLID Principles: Dependency Inversion Principle

    SOLID Principles: Dependency Inversion Principle

    Solid Principles: Interface Segregation Principle

    Solid Principles: Interface Segregation Principle

    Tìm hiểu về composer.json schema (phần 2 – autoload)

    Tìm hiểu về composer.json schema (phần 2 – autoload)

    IPC – Đằng sau sự thành công của Chromium

    IPC – Đằng sau sự thành công của Chromium

    Dựng layout website với CSS Grid Layout

    Dựng layout website với CSS Grid Layout

    Golang cơ bản (p1)

    Golang cơ bản (p1)

    Trending Tags

    • Idea
    • Lifestyle
    No Result
    View All Result
    • Home
    • News
    • Dev
      • All
      • Algorithm
      • Architecture
      • Database
      • Design
      • DevOps
      • IoT
      • Network
      • Test
      • Web
      Phương thức xử lý mảng trong javascript

      Phương thức xử lý mảng trong javascript

      Bảo vệ content, chống copy nội dung web!

      Bảo vệ content, chống copy nội dung web!

      Lưu ý mệnh đề NOT IN trong SQL

      Lưu ý mệnh đề NOT IN trong SQL

      SOLID Principles: Dependency Inversion Principle

      SOLID Principles: Dependency Inversion Principle

      Solid Principles: Interface Segregation Principle

      Solid Principles: Interface Segregation Principle

      Tìm hiểu về composer.json schema (phần 2 – autoload)

      Tìm hiểu về composer.json schema (phần 2 – autoload)

      IPC – Đằng sau sự thành công của Chromium

      IPC – Đằng sau sự thành công của Chromium

      Dựng layout website với CSS Grid Layout

      Dựng layout website với CSS Grid Layout

      Golang cơ bản (p1)

      Golang cơ bản (p1)

      Trending Tags

      • Idea
      • Lifestyle
      No Result
      View All Result
      DEVZONE
      No Result
      View All Result
      Home Dev Algorithm

      JSON Web Token và những điều bạn chưa biết

      Tuấn Anh Zippy by Tuấn Anh Zippy
      February 1, 2020
      in Algorithm, Dev, Web
      0
      json-web-token

      Ngoảnh đi ngoảnh lại cái lại hết một năm rồi đấy các bác ạ. Năm vừa rồi các bác đã làm được gì rồi, em thì vẫn lôm côm lắm, chẳng ra đâu vào với đâu cả. Thôi không lan man dài dòng nữa vào luôn chủ đề nhé.

      Chắc các bạn đã nghe tới JWT rồi chứ, cứ nghe đến cái này thì mình liên tưởng đến xác thực một cái gì đó, hôm nay rảnh háng, ngồi đọc nghiên cứu thêm xem có vài ký tự lằng nhằng trông thế thôi mà bảo mật phết các bác ạ.

      Đối với bất kỳ một ứng dụng web, di động, desktop…vv chắc chắn các bạn đều đã từng tạo tài khoản, sau đó phải đăng nhập để sử dụng các tính năng bên trong của ứng dụng, hành động đó gọi là Authentication – xác thực người dùng.

      Vậy thì xác thực người dùng bằng cách nào?

      Mình copy cái ảnh này nhé. Cảm ơn tác giả 😀 Thường thì chúng ta vẫn làm như này đúng không nào, ok, chẳng vấn đề gì 😀 Cơ mà giờ mà sau này chúng ta phát triển thêm cho các Mobile Apps, TV Apps,… thì chẳng lẽ lại dùng cách trên @@ cơ mà có phải trình duyệt đâu mà có Session với Cookie.

      Toang rồi, giờ phải làm sao. Để giải quyết được vấn đề trên thì JWT đã được ra đời.

      JWT là gì ?

      JSON Web Token (JWT) là 1 tiêu chuẩn mở (RFC 7519 bạn nào tốt ngoại ngữ thì đọc ở đây nhé. Bách khoa toàn thư, đọc chả hiểu gì @@) định nghĩa cách thức truyền tin an toàn giữa các ứng dụng với nhau(web, app, tv,…) bằng 1 đối tượng JSON. Thông tin này có thể được xác thực và đánh dấu tin cậy nhờ vào “chữ ký” của nó. Phần chữ ký của JWT sẽ được mã hóa lại bằng HMAC hoặc RSA.

      Ví dụ đây sẽ là một chuỗi JWT: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0b3B0YWwuY29tIiwiZXhwIjoxNDI2NDIwODAwLCJodHRwOi8vdG9wdGFsLmNvbS9qd3RfY2xhaW1zL2lzX2FkbWluIjp0cnVlLCJjb21wYW55IjoiVG9wdGFsIiwiYXdlc29tZSI6dHJ1ZX0.yRQYnWzskCZUxPwaQupWkiUzKELZ49eM7oWxAQK_ZXw

      Đó các bạn nhìn thấy chưa, chả hiểu gì 😀 cơ mà để ý kỹ nhé. Có 2 dấu chấm xuất hiện trong chuỗi này. Đó chính là cấu trúc của JWT. JSON Web Token bao gồm 3 phần, được ngăn cách nhau bởi dấu chấm (.):

      • Header

      • Payload

      • Signature

      <base64-encoded header>.<base64-encoded payload>.<base64-encoded signature>

      Cùng tìm hiểu sâu hơn xem bên trong 3 cái này gồm những gì nhé.

      1. Header: bao gồm hai phần chính: loại TOKEN(mặc định là JWT ngoài ra còn JWS hay JWE nữa cơ, xịn sò lắm) và ALGORITHM là thuật toán mã hóa: ở đây có rất nhiều: HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512, PS256, PS384.

      Ví dụ cái cho dễ hiểu nhé:

      {
        "alg": "HS256",
        "typ": "JWT"
      }
      

      Đơn giản nhỉ, nó chỉ là JSON object thôi mà bao gồm key: value. Ở ví dụ trên HS256 là thuật toán có tên HMAC-SHA256, một thuật toán băm sử dụng khóa bí mật (Secret Key) để tính toán tạo ra chữ ký.

      Giờ mình sẽ Encode Base64URL cái này. Không phải Base64 mà các bạn vẫn hay dùng đâu, khác ở đây là:

      • Không thêm = vào

      • Các ký tự + và / sẽ được thay thế bằng – và _

      Mình viết bằng NodeJS sử dụng thư viện CryptoJS nhé:

      var CryptoJS = require("crypto-js");
      
      function base64Url(source) {
      
        // Encode in classical base64
        var encryptedWord = CryptoJS.enc.Utf8.parse(source);
        var encodedSource = CryptoJS.enc.Base64.stringify(encryptedWord);
      
        // Remove padding equal characters
        encodedSource = encodedSource.replace(/=+$/, '');
      
        // Replace characters according to base64url specifications
        encodedSource = encodedSource.replace(/\+/g, '-');
        encodedSource = encodedSource.replace(/\//g, '_');
      
        return encodedSource;
      }
      console.log(base64Url(JSON.stringify({"alg": "HS256", "typ": "JWT"})));

      Kết quả: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

      1. Payload: nơi chứa các nội dung của thông tin (claim). Thông tin truyền đi có thể là mô tả của 1 thực thể (ví dụ như người dùng) hoặc cũng có thể là các thông tin bổ sung thêm cho phần Header. Nhìn chung, chúng được chia làm 3 loại: reserved, public và private.

      Reserved: là những thông tin đã được quy định ở trong IANA JSON Web Token Claims registry. Chúng bao gồm: Chú ý rằng các khóa của claim đều chỉ dài 3 ký tự vì mục đích giảm kích thước của Token.

      • iss (issuer): tổ chức phát hành token

      • sub (subject): chủ đề của token

      • aud (audience): đối tượng sử dụng token

      • exp (expired time): thời điểm token sẽ hết hạn

      • nbf (not before time): token sẽ chưa hợp lệ trước thời điểm này

      • iat (issued at): thời điểm token được phát hành, tính theo UNIX time

      • jti: JWT ID

      Public: Khóa nên được quy định ở trong IANA JSON Web Token Registry, cái này không bắt buộc do mình tạo thôi

      Private: Phần thông tin thêm dùng để truyền qua giữa các ứng dụng client.

      Bonus cho cái ví dụ cho dễ hình dung nhé:

      var payload = {
        "jwi": 11111995,
        "iss": "MegaAds Blog",
        "sub": "JWT Implement",
        "iat": 1580397974,
        "exp": 1580484374,
        "aud": ["web","app","smart-tv"],
        "data": {
             "id": "64hjg-54bfjyp-ebfjuzd-5k39-dsfjskljf43",
             "username": "tuananhzippy",
             "occupation": "Full Stack Web Developer",
        },
        "website": "http://blog.megaads.vn"
      };
      
      console.log(base64Url(JSON. stringify(payload))); 

      Kết quả: eyJqd2kiOjExMTExOTk1LCJpc3MiOiJNZWdhQWRzIEJsb2ciLCJzdWIiOiJKV1QgSW1wbGVtZW50IiwiaWF0IjoxNTgwMzk3OTc0LCJleHAiOjE1ODA0ODQzNzQsImF1ZCI6WyJ3ZWIiLCJhcHAiLCJzbWFydC10diJdLCJkYXRhIjp7ImlkIjoiNjRoamctNTRiZmp5cC1lYmZqdXpkLTVrMzktZHNmanNrbGpmNDMiLCJ1c2VybmFtZSI6InR1YW5hbmh6aXBweSIsIm9jY3VwYXRpb24iOiJGdWxsIFN0YWNrIFdlYiBEZXZlbG9wZXIifSwid2Vic2l0ZSI6Imh0dHA6Ly9ibG9nLm1lZ2FhZHMudm4ifQ

      1. Signature: Phần chữ ký được tạo bằng cách kết hợp 2 phần Header + Payload, rồi mã hóa nó lại bằng 1 giải thuật mã hóa nào đó, càng phức tạp thì càng tốt, ví dụ như HMAC SHA-256. Cùng tìm hiểu một chút về HMAC nhé:

      Đầu tiên ta phải hiểu MAC là gì: Message Authentication Code là một chuỗi các bit được gửi cùng với một tin nhắn(ở đây có thể là dữ liệu của chúng ta). MAC phụ thuộc vào chính thông điệp và khóa bí mật(mã hóa đối xứng). Không ai có thể tính toán MAC mà không biết khóa. Điều này cho phép hai người chia sẻ một khóa bí mật để gửi tin nhắn cho nhau mà không sợ người khác sẽ can thiệp vào tin nhắn. (Ít nhất, nếu ai đó không làm xáo trộn với một thông điệp, điều này có thể được phát hiện bằng cách kiểm tra để xem nếu MAC là đúng.)

      HMAC là một công thức để biến các hàm băm (như MD5 hoặc SHA256) thành MAC. Vì vậy, HMAC-MD5 và HMAC-SHA256 là các thuật toán MAC cụ thể, giống như QuickSort là một thuật toán sắp xếp cụ thể.

      Quay lại với JWT, giờ thì ta đem Header + “.” + Payload đi mã hóa là ta có một JWT hoàn chỉnh.

      Để mã hóa ta cần chọn 1 Secret key. Khóa này chính là mấu chốt của vấn đề. Đừng để lộ cái này ra nhé, không là toang đấy

      var secretKey = 'Il@vEy0U%123';
      var token = encodeHeader + '.' + encodePayload;
      var signature = CryptoJS.HmacSHA256(token, secretKey);
      signature = base64Url(signature);

      Sau khi mã hóa HMACSHA256 ta lại tiếp tục đem đi Base64 nó. Vậy là xong rồi đem đi nối vào phần còn lại như công thức Header + Payload + Signature;

      var signedToken = token + '.' + signature;
      console.log('Signed Token', signedToken);

      Kết quả: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqd2kiOjExMTExOTk1LCJpc3MiOiJNZWdhQWRzIEJsb2ciLCJzdWIiOiJKV1QgSW1wbGVtZW50IiwiaWF0IjoxNTgwMzk3OTc0LCJleHAiOjE1ODA0ODQzNzQsImF1ZCI6WyJ3ZWIiLCJhcHAiLCJzbWFydC10diJdLCJkYXRhIjp7ImlkIjoiNjRoamctNTRiZmp5cC1lYmZqdXpkLTVrMktZHNmanNrbGpmNDMiLCJ1c2VybmFtZSI6InR1YW5hbmh6aXBweSIsIm9jY3VwYXRpb24iOiJGdWxsIFN0YWNrIFdlYiBEZXZlbG9wZXIifSwid2Vic2l0ZSI6Imh0dHA6Ly9ibG9nLm1lZ2FhZHMudm4ifQ.YThjMjczZDBjMDliYTgzYzYxMTJkMzM0MWIwNDlkMzJmYzcyNDVmNDYwZjQwNDk1ZDEyYWE4OThlYWRhYmIzMg

      JWT bảo vệ dữ liệu của chúng ta bằng cách nào?

      JWT không bảo vệ dữ liệu của bạn. JWT nó không ẩn, không làm mờ, không che giấu dữ liệu, mà nó được sử dụng để chứng minh rằng dữ liệu được tạo ra bởi một nguồn xác thực.

      Các bạn có thể nhìn lại ở các bước xử lý Header, Payload, Signature trên kia, dữ liệu chỉ được Encoded và Hash (Signed) chứ không phải Encrypted. Úi có cái này mới này Encode va Encrypt tưởng nó giống nhau mà nhỉ, cơ mà không phải 😀

      • Encoding transforms data into another format using a scheme that is publicly available so that it can easily be reversed. (tạm dịch là biến đổi dữ liệu sang một định dạng khác bằng cách sử dụng các sơ đồ có sẵn công khai, ai cũng có thể đọc và giải mã một cách dễ dàng)
      • Encryption transforms data into another format in such a way that only specific individual(s) can reverse the transformation. (tạm dịch là biến đổi dữ liệu sang một định dạng khác theo cách mà chỉ cá nhân cụ thể mới có thể giải mã, người biết mới có thể giải mã)
      • Nguồn: http://danielmiessler.com/study/encoding_vs_encryption/

       

      Vậy thì có bạn sẽ đặt ra thắc mắc: “nếu một kẻ tấn công ở giữa (Man-in-the-middle) bắt được gói tin có chứa mã JWT rồi họ decode ra và lấy được thông tin của user thì sao?” 😀 đừng lo lắng vì đã có HTTPS.

      Server xác thực mã JWT gửi lên từ client ra sao?

      Trong phần 3 trên kia các bạn hãy nhìn lại cho mình đó là khi tạo mã JWT, chúng ta có sử dụng tới một chuỗi bí mật “Secret” trong bước tạo chữ ký (signature).

      Chuỗi “Secret” này là unique cho ứng dụng và phải được ưu tiên lưu trữ bảo mật cẩn thận ở phía server. Khi nhận được mã Token gửi lên từ phía client, Server sẽ lấy phần Signature (chữ ký) bên trong mã token đó, và verify (kiểm tra) xem cái chữ ký nhận được có đúng chính xác là được HASH (băm) bởi cùng một thuật toán và chuỗi “Secret” như trên hay không.


      Tổng kết lại thì bài viết vừa rồi mình có đề cập tới JWT trên khía cạnh lý thuyết và các thức thực hiện. Khi gặp bài toán cụ thể ta sẽ vận dụng nó theo nhiều cách khác nhau(accessToken, refeshToken). Nhưng túm lại thì JWT nó chỉ có thế 😀

      Qua bài viết này mình mong muốn giúp cho những ai còn chưa hiểu nhiều về JWT hoặc chưa hiểu về nó thì có thể hình dung được phần nào những lợi ích mà nó đem lại cho Web Service.

      Chúc các bạn thành công, xin chào và hẹn gặp lại!

      Tham khảo:

      1. https://trungquandev.com/hieu-sau-ve-jwt-json-web-tokens/
      2. https://auth0.com/resources/ebooks/jwt-handbook
      3. https://techmaster.vn/posts/33959/khai-niem-ve-json-web-token

       

      Thả tim (5 lượt thả tim)
      Loading...
      Previous Post

      Xây dựng Email Server với Postfix, Dovecot và Roundcube: #3 – Sử dụng nhiều domain email và một số cấu hình

      Next Post

      Facade Pattern

      Tuấn Anh Zippy

      Tuấn Anh Zippy

      Rất gì và này nọ...

      Next Post
      Facade Pattern

      Facade Pattern

      Leave a Reply Cancel reply

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

      Recent News

      Lập trình viên không dùng máy Mac nhiều như người ta đã nghĩ

      Lập trình viên không dùng máy Mac nhiều như người ta đã nghĩ

      July 25, 2020
      Dấu hiệu nhận biết sức khỏe qua liềm móng tay

      Dấu hiệu nhận biết sức khỏe qua liềm móng tay

      June 26, 2020
      Phương thức xử lý mảng trong javascript

      Phương thức xử lý mảng trong javascript

      May 31, 2020
      Lợi ích của việc tập thể dục thường xuyên

      Lợi ích của việc tập thể dục thường xuyên

      May 25, 2020
      DEVZONE

      Browse by Category

      • Algorithm
      • Architecture
      • Database
      • Design
      • Dev
      • DevOps
      • Idea
      • IoT
      • Lifestyle
      • Network
      • News
      • Test
      • Uncategorized
      • Web
      • About
      • Advertise
      • Privacy & Policy
      • Contact

      © 2019 Devzone

      No Result
      View All Result

      © 2019 Devzone