1. [NodeJS + VueJS] Create Pagination
  2. Chat NodeJS + VueJS
  3. Create Form Register using Nodejs + Vuejs
  4. Create Login in React Native and NodeJS
  5. Hướng dẫn cài đặt Nodejs trên localhost
  6. Hướng dẫn kết hợp Nodejs + Vuejs
  7. Hướng dẫn kết nối Mysql trong Nodejs
  8. insert-update-delete Mysql bằng Nodejs
  9. Video Create Form Register and Login + Chat Real Time Using Nodejs + Vuejs
  10. Tạo ứng dụng đầu tiên bằng Nodejs
  11. Crawl Data Website Using NodeJS
  12. Create Image Watermark using Nodejs
  13. JWT(Json Web Token) in Node.js

JWT(Json Web Token) in Node.js

min read
Tags: NodeJS

Xin chào mọi người, nay mình chia sẻ với mọi người cách sử dụng JWT(Json Web Token) trong Node.js. Để dùng được JWT thì chúng ta phải sử dụng thư viện sau : 

$ npm install jsonwebtoken

Thư viện trên giúp ta có thể tạo Token để lưu thông tin data người dùng, khi họ đăng nhập vào chương trình thành công, ta sẽ dùng chuổi Token đó, request truy xuất lấy thông tin người dùng, thường hay dùng trong Restful API xây dựng giữa Client và Server

Bạn có thể tìm hiểu thêm về thư viện này tại đây : https://www.npmjs.com/package/jsonwebtoken

Demo:

 

Okay, giờ mình tạo một project và cài đặt một số thư viện sau :

npm init 
npm install express body-parser jsonwebtoken sqlite3 dotenv cors nodemon 

Mình sẽ nói sơ qua các thư viện trên như sau : 

+ body-parser : Mình cứ hiểu là nó dùng phân tích dữ liệu Data, khi người dùng gửi đến server, bạn có thể tùy chọn phân tích dữ liệu (JSON body parser, Raw body parser, Text body parser, URL-encoded form body parser), bạn có thể xem thêm tại đây : https://www.npmjs.com/package/body-parser
+ jsonwebtoken : Giúp ta tạo mã Token, khi dười dùng Register & Login, dùng mã token đó lấy thông tin ra, kiểm tra thời gian của token, nếu hết hạn thì xử lý nó thế nào tùy bạn
+ sqlite3 : Sử dụng SQLite3 giúp ta tạo database quản lý dữ liệu, truy vấn các câu lệnh query(insert, select,update,delete,....). Bạn có thể xem thêm tại đây :  https://www.sqlitetutorial.net/sqlite-nodejs/query/
+ dotenv : Giúp ta tạo file .env quản lý một số key bí mật chương trình
+ cors : Cái này thì nhiều bạn biết, nếu xây server, khi có bắt cứ chỉnh sửa thao tác gì trong code, thì tự động restart lại server, thuận tiện cho việc chỉnh sửa code trong Node.js

Mình chỉ  hiểu sao, nói đơn giản là vậy, các bạn có thể tìm hiểu thêm về các thư viện trên, thật sự mình còn chưa hiểu hết về chúng, chỉ sử dụng những cái cần làm thôi, ::)

Đầu tiên mình xây dựng một database lưu thông tin users, bạn hãy lên mạng tìm kiếm và tải phần mềm sqlite về dùng https://sqlitebrowser.org/dl/

CREATE TABLE "users" (
	"id"	INTEGER,
	"first_name"	TEXT NOT NULL,
	"last_name"	TEXT NOT NULL,
	"email"	TEXT NOT NULL UNIQUE,
	"password"	TEXT NOT NULL,
	"token"	TEXT,
	PRIMARY KEY("id" AUTOINCREMENT)
);

Sau khi tạo xong database nhớ lưu đến project của bạn, để tí ta dùng đến, Okay, bước đầu đã có database rồi, giờ ta đi thẳng vào chương trình luôn.

Hãy tạo file App.js và dán mã bên dưới vào 

require("dotenv").config();
const express = require("express");
const jwt = require("jsonwebtoken");
const app = express();
app.use(express.json());

/* DATA SIMBLE */
const sqlite3 = require('sqlite3').verbose();
// Setup the database connection
let conn = new sqlite3.Database("./database.db", err => {
    if (err) {
        return console.error(err.message);
    }
    console.log("Connected to the in-memory SQLite database.");
});

app.post("/welcome", (req, res) => {
    const token =
        req.body.token || req.query.token || req.headers["x-access-token"];
  
    if (!token) {
        return res.status(403).send("A token is required for authentication");
    }
    try {
        var decoded = jwt.verify(token, process.env.TOKEN_KEY);
        res.status(200).send(decoded.user);
    } catch (err) {
        return res.status(401).send("Invalid Token");
    }
   
});
// Register
app.post("/register", async (req, res) => {

    // Our register logic starts here
    try {
        // Get user input
        const { first_name, last_name, email, password } = req.body;

        // Validate user input
        if (!(email && password && first_name && last_name)) {
            res.status(400).send("All input is required");
        }else{
            var sql = "INSERT INTO users(first_name,last_name,email,password) values('" + first_name + "','" + last_name + "','" + email + "','" + password + "')";
            conn.serialize(()=>{
                conn.run(
                   sql, function (err) {
                       if (err) {
                           res.status(500).json(err.message);
                       }else{
                            let lastID = this.lastID;
                            res.status(200).json({"success":1,"lastID":lastID});
                       }
                   }
               );
               
            });
        }

        /* save user to databse */
    } catch (err) {
        console.log(err);
    }

});

// Login
app.post("/login", async (req, res) => {

   
        const { email, password } = req.body;


        if (!(email && password)) {
            res.status(400).send("All input is required");
        }

        conn.serialize(()=>{
            conn.get("select * from users where email=? and password=?", [email, password],async  function (err, row) {
                if(err){
                    res.status(500).send({'Response':'Error updating user', err });   
                }
                if(row){
                    
                    let _id = row.id;
                    const {first_name,last_name,email} = row;
                    var user ={first_name,last_name,email};
                    var token = jwt.sign({ exp: Math.floor(Date.now() / 1000) + (60 * 60), user: user }, process.env.TOKEN_KEY);
                    conn.run("update users set token=? where id=?", [token, _id], function (err2) {
                        if (err2) {
                            res.status(400).json({ "description": "Đăng nhập không thành công" });
                        }else{
                            res.status(200).json(token);
                        }
                    });
                }else{
                    res.status(500).json({"success":0});
                }
               
            });
        })
       
});

module.exports = app;

Bạn nhìn đoạn code trên đầu tiên ta cần gọi một số thư viện mà ban đầu ta đã cài đặt

require("dotenv").config();
const express = require("express");
const jwt = require("jsonwebtoken");
const sqlite3 = require('sqlite3').verbose();

Mình có gọi require("dotenv").config(), cho nên bạn cần tạo file .env trong project , lưu các KEY mà bạn cần dùng đến

API_PORT=4001
TOKEN_KEY=webtoken123

Để sử dụng được file .env bạn cần sử dụng câu lệnh process.env.TOKEN_KEY

Tiếp theo ta cần khai báo connect đến databsae trong sqlite, sử dụng câu lên bên dưới

let conn = new sqlite3.Database("./database.db", err => {
    if (err) {
        return console.error(err.message);
    }
    console.log("Connected to the in-memory SQLite database.");
});

Các bạn có thể tìm hiểu về các câu truy vấn Query như (insert, update, select,...) trong SQLite tại đây : https://www.sqlitetutorial.net/sqlite-insert/

Ta có hàm khởi tạo Token trong đoạn code trên, ta cần khai báo thời gian hết hạn của token, để khi hết token, thì ta có thể thông báo cho người dùng biết phiên làm việc đã hết hạn, lúc đó tùy bạn muốn xử lý sao thì tùy
Mình khởi tạo Token có thời gian là 60 phút

var token = jwt.sign({ exp: Math.floor(Date.now() / 1000) + (60 * 60), user: data }, process.env.TOKEN_KEY);

Làm sao để lấy được Token ta dùng đoạn code sau để lấy Token trong Request Header

const token = req.body.token || req.query.token || req.headers["x-access-token"];

Thêm người dùng đăng ký vào database, dưới đây là phương thức run, ta chỉ cần viết câu query vào trong phương thức run , kèm theo tham số là được

db.run(sql, params, function(err){
  // 
});
db.run(`INSERT INTO langs(name) VALUES(?)`, ['C'], function(err) {
    if (err) {
      return console.log(err.message);
    }
    // get the last insert id
    console.log(`A row has been inserted with rowid ${this.lastID}`);
});

Bạn có thể tìm hiểu thêm một số query trong SQLite tại đây :  https://www.sqlitetutorial.net/sqlite-nodejs/query/

Giờ hãy tạo file index.js trong project và viết code khởi chạy server với port gì đó mà bạn đã cung cấp trong file .env

const http = require("http");
const app = require("./app");
const server = http.createServer(app);

const { API_PORT } = process.env;
const port = process.env.PORT || API_PORT;

// server listening 
server.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

Code trên bạn cần nhớ khai bao file app.js vào nhé , giờ hãy mở file package.json chỉnh lại câu lệnh chạy server , bạn nhìn trong "scripts"

{
  "name": "nodejs-react",
  "version": "1.0.0",
  "description": "nodejs react",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "nodejs",
    "react"
  ],
  "author": "hoanguyenit",
  "license": "ISC",
  "dependencies": {
    "bcryptjs": "^2.4.3",
    "body-parser": "^1.19.0",
    "cors": "^2.8.5",
    "dotenv": "^10.0.0",
    "express": "^4.17.1",
    "jsonwebtoken": "^8.5.1",
    "mongoose": "^6.0.9",
    "sqlite3": "^5.0.2",
    "uid": "^2.0.0"
  },
  "devDependencies": {
    "nodemon": "^2.0.13"
  }
}

Okay, ta chạy câu lệnh dưới đây khởi động server thôi

npm run dev

Test trong project của chúng ta có các bước sau :
Bước 1: request post("/register") đăng ky thành viên
Bước 2: post("/login") nếu đăng nhập đúng, tạo token lưu thông tin người dùng
Bước 3: post("/welcome"), kèm mã token vào header, để gửi đến server xử lý để lấy thông tin dữ liệu người dùng đã đăng nhập thành công trước đó

Vậy là xong, hẹn bài viết chia sẻ kiến thức tiếp theo ::)

 

Tags: NodeJS
x

Ủng hộ tôi bằng cách click vào quảng cáo. Để tôi có kinh phí tiếp tục phát triển Website!(Support me by clicking on the ad. Let me have the money to continue developing the Website!)