Thứ tư, 19/02/2020 | 00:00 GMT+7

Mã thông báo web JSON (JWT) trong Express.js


Bài viết này được viết trên các ứng dụng của JSON Web Tokens (JWTs) trong mối quan hệ server -máy khách sử dụng Node.js và vanilla JavaScript. Nếu bạn muốn tìm hiểu về các khái niệm đằng sau JWT, tôi không thể giới thiệu bài đăng trên Medium của Mariano Calandra nhiều hơn.

Để cài đặt Mã thông báo web JSON trong dự án của bạn, hãy chạy:

$ yarn add jsonwebtoken

Và nhập nó vào các file của bạn như sau:

const jwt = require("jsonwebtoken");

Xác thực mã thông báo

Có nhiều cách để triển khai hệ thống xác thực JWT trong ứng dụng Express.js . Tuy nhiên, điều gì phù hợp nhất với tôi, đó là sử dụng chức năng phần mềm trung gian của Express.js. Cách hoạt động khi một yêu cầu được thực hiện đến một tuyến cụ thể, bạn có thể gửi các biến (req, res) đến một hàm trung gian trước biến được chỉ định trong app.get((req, res) => {}) .

Phần mềm trung gian là một hàm nhận các tham số của (req, res, next) . Yêu req là yêu cầu đã gửi ( lấy, đăng, xóa, sử dụng, v.v. ), res là phản hồi có thể được gửi lại cho user theo nhiều cách (res.sendStatus (200), res.json () , v.v.), và next là một hàm có thể được gọi để di chuyển quá trình thực thi qua phần phần mềm trung gian và vào phản hồi server app.get thực tế.

Đây là chức năng phần mềm trung gian tôi đã viết cho nhu cầu xác thực của bạn :

function authenticateToken(req, res, next) {
  // Gather the jwt access token from the request header
  const authHeader = req.headers['authorization']
  const token = authHeader && authHeader.split(' ')[1]
  if (token == null) return res.sendStatus(401) // if there isn't any token

  jwt.verify(token, process.env.ACCESS_TOKEN_SECRET as string, (err: any, user: any) => {
    console.log(err)
    if (err) return res.sendStatus(403)
    req.user = user
    next() // pass the execution off to whatever request the client intended
  })
}

Một yêu cầu ví dụ sử dụng chức năng phần mềm trung gian này sẽ trông giống như sau:

GET https://mysite:4000/api/userOrders
Authorization: Bearer JWT_ACCESS_TOKEN

Và, một ví dụ về yêu cầu sử dụng phần mềm trung gian đó sẽ trông như thế này:

// ...
app.get('/api/userOrders', authenticateToken, (req, res) => {
  // executes after authenticateToken
  // ...
})
// ...

Tạo mã thông báo

Backtracking, bây giờ ta sẽ thảo luận về cách tạo và gửi mã thông báo JWT cho khách hàng.

Để thực hiện điều này (đây là ký mã thông báo), bạn cần có 3 thông tin:

  1. Bí mật mã thông báo
  2. Phần dữ liệu để băm trong mã thông báo
  3. Thời gian hết hạn của mã thông báo

Bí mật mã thông báo chỉ đơn giản là một chuỗi siêu dài, siêu ngẫu nhiên được sử dụng để mã hóa và giải mã dữ liệu. Để tạo ra bí mật này, tôi khuyên bạn sử dụng Node của crypto thư viện, như vậy:

> require('crypto').randomBytes(64).toString('hex')
// '09f26e402586e2faa8da4c98a35f1b20d6b033c6097befa8be3486a829587fe2f90a832bd3ff9d42710a4da095a2ce285b009f0c3730cd9b8e1af3eb84df6611'

Hãy cẩn thận! Nếu 'bí mật' của bạn đơn giản, quá trình xác minh mã thông báo sẽ dễ dàng hơn nhiều bởi kẻ xâm nhập trái phép.

Bây giờ hãy lưu trữ bí mật này trong file .env của dự án của bạn:

.env
TOKEN_SECRET=7bc78545b1a3923cc1e1e19523fd5c3f20b409509...

Để đưa mã thông báo này vào file Node và để sử dụng nó, bạn phải sử dụng dotenv :

const dotenv = require("dotenv");

// get config vars
dotenv.config();

// access config var
process.env.TOKEN_SECRET;

Phần dữ liệu mà bạn băm trong mã thông báo của bạn có thể là một thứ gì đó đơn giản như ID user hoặc tên user , cho đến một đối tượng phức tạp hơn nhiều. Trong cả hai trường hợp, nó phải là một số nhận dạng cho một user cụ thể .

Thời gian hết hạn của mã thông báo là một chuỗi, chẳng hạn như '1800s' nêu chi tiết thời gian cho đến khi mã thông báo hết hiệu lực.

Vì vậy, đây là một chức năng để ký mã thông báo:

// username is in the form { username: "my cool username" }
// ^^the above object structure is completely arbitrary
function generateAccessToken(username) {
  // expires after half and hour (1800 seconds = 30 minutes)
  return jwt.sign(username, process.env.TOKEN_SECRET, { expiresIn: '1800s' });
}

Điều này có thể được gửi lại từ một yêu cầu đăng nhập hoặc đăng nhập một user .

app.post('/api/creteNewUser', (req, res) => {
  // ...
  const token = generateAccessToken({ username: req.body.username });
  res.json(token);
  // ...
});

Xử lý mã thông báo phía client

Khi khách hàng nhận được mã thông báo, họ thường muốn lưu trữ nó để thu thập thông tin user trong các yêu cầu trong tương lai. Cách phổ biến nhất để lưu trữ mã thông báo xác thực là cookielocalStorage . Đây là cách triển khai để lưu trữ cookie bằng mã JavaScript phía client :

...
// get token from fetch request
const token = await res.json();

// set token in cookie
document.cookie = `token=${token}`
// ...

Và với localStorage, điều đó thật dễ dàng:

const token = await res.json();

localStorage.setItem('token', token);

Nó đơn giản mà!


Tags:

Các tin liên quan

Phát triển bản địa với API thông báo web
2020-02-12
Cách tạo ứng dụng chuyển văn bản thành giọng nói với API giọng nói trên web
2019-12-12
Cách tạo băng chuyền image danh mục đầu tư với các thanh trượt được đồng bộ hóa trên trang web
2019-12-12
Cách tạo thông báo trên web bằng kênh Laravel và Pusher
2019-12-12
Khả năng truy cập web cho người mới bắt đầu
2019-12-12
Cách cài đặt web server OpenLiteSpeed trên Ubuntu 18.04
2019-12-02
Sử dụng Phông chữ Google trong các Trang web của bạn
2019-08-22
Cách triển khai ứng dụng web Go bằng Nginx trên Ubuntu 18.04
2019-07-24
Biến Gatsby thành PWA: Service Worker và Web App Manifest
2019-07-18
Giới thiệu về Kiểm tra trực quan cho Ứng dụng Web
2019-06-11