Latest Post

Tăng thứ hạng và truy cập tự nhiên với 10 phương pháp SEO hay nhất Kiếm Tiền Online (mmo): Khái Niệm và Các Hình Thức Phổ Biến

Bài này chúng ta sẽ từng bước xây dựng một Rest API bằng TypeScript, Express.js và TypeORM với xác thực và phân quyền cơ bản bằng JWT. TypeORM cho phép bạn chỉ cần viết một class và công cụ đồng bộ hóa sẽ tự động tạo ra cấu trúc SQL cho entity của bạn. Nó tương thích với nhiều cơ sở dữ liệu khác nhau như MySQL, MariaDB, Postgres, SQLite, Microsoft SQL Server, Oracle, sql.js, và MongoDB. Trong project này, chúng ta sẽ sử dụng SQLite để thuận tiện cho việc phát triển và thử nghiệm. Hãy cùng khám phá cách cài đặt và cấu hình dự án để xây dựng một hệ thống xác thực mạnh mẽ với JWT.

Bước 1: Cài đặt và khởi tạo dự án Node.js với TypeScript

Trước tiên, hãy tạo một thư mục mới và khởi tạo dự án Node.js:

mkdir ts-express-typeorm
cd ts-express-typeorm
npm init -y

Tiếp theo, cài đặt các dependencies cần thiết:

npm install express typeorm reflect-metadata sqlite3 jsonwebtoken bcryptjs
npm install --save-dev typescript ts-node @types/node @types/express @types/jsonwebtoken @types/bcryptjs

Bước 2: Thiết lập TypeScript

Tạo file tsconfig.json để cấu hình TypeScript:

{
  "compilerOptions": {
    "target": "ES6",
    "module": "commonjs",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  }
}

Bước 3: Cấu trúc dự án

Tạo các thư mục và file cần thiết cho dự án:

mkdir src
cd src
touch app.ts
mkdir controllers routes entities middleware

Bước 4: Cấu hình TypeORM

Tạo file ormconfig.json để cấu hình TypeORM:

{
  "type": "sqlite",
  "database": "database.sqlite",
  "synchronize": true,
  "logging": false,
  "entities": ["src/entities/**/*.ts"],
  "migrations": ["src/migration/**/*.ts"],
  "subscribers": ["src/subscriber/**/*.ts"],
  "cli": {
    "entitiesDir": "src/entities",
    "migrationsDir": "src/migration",
    "subscribersDir": "src/subscriber"
  }
}

Bước 5: Tạo Entity

Tạo entity User trong thư mục entities:

// src/entities/User.ts
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
import { IsEmail, Length } from 'class-validator';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  @Length(4, 20)
  username: string;

  @Column()
  @IsEmail()
  email: string;

  @Column()
  @Length(8, 100)
  password: string;
}

Bước 6: Tạo Controller và Route

Tạo controller cho người dùng trong thư mục controllers:

// src/controllers/UserController.ts
import { Request, Response } from 'express';
import { getRepository } from 'typeorm';
import { User } from '../entities/User';
import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';

export class UserController {
  static register = async (req: Request, res: Response) => {
    const { username, email, password } = req.body;
    const userRepository = getRepository(User);
    const user = new User();
    user.username = username;
    user.email = email;
    user.password = bcrypt.hashSync(password, 8);

    try {
      await userRepository.save(user);
    } catch (error) {
      return res.status(409).send("username already in use");
    }
    res.status(201).send("User created");
  };

  static login = async (req: Request, res: Response) => {
    const { email, password } = req.body;
    const userRepository = getRepository(User);
    let user: User;

    try {
      user = await userRepository.findOneOrFail({ where: { email } });
    } catch (error) {
      return res.status(401).send("User not found");
    }

    if (!bcrypt.compareSync(password, user.password)) {
      return res.status(401).send("Incorrect password");
    }

    const token = jwt.sign(
      { userId: user.id, username: user.username },
      process.env.JWT_SECRET,
      { expiresIn: "1h" }
    );

    res.send({ token });
  };
}

Tạo routes cho người dùng trong thư mục routes:

// src/routes/user.ts
import { Router } from 'express';
import { UserController } from '../controllers/UserController';

const router = Router();

router.post('/register', UserController.register);
router.post('/login', UserController.login);

export default router;

Bước 7: Thiết lập Express

Thiết lập server Express trong app.ts:

// src/app.ts
import 'reflect-metadata';
import * as express from 'express';
import * as bodyParser from 'body-parser';
import { createConnection } from 'typeorm';
import userRouter from './routes/user';

const app = express();

app.use(bodyParser.json());

app.use('/user', userRouter);

createConnection().then(() => {
  app.listen(3000, () => {
    console.log('Server started on port 3000');
  });
}).catch(error => console.log(error));

Kết luận

Với các bước trên, bạn đã thiết lập thành công một ứng dụng Rest API với TypeScript, Express.js, TypeORM, JWT xác thực và phân quyền cơ bản. Bạn có thể dễ dàng chuyển đổi giữa các cơ sở dữ liệu mà không cần thay đổi mã nguồn và mở rộng dự án của mình bằng cách thêm các chức năng và routes mới. Hãy thử nghiệm và tùy chỉnh dự án này theo nhu cầu của bạn để học TypeScript hiệu quả hơn.

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *