# NestJS & Passport & JWT ###### tags: `NestJS` `JWT` `bcrypt` `Passport` <!-- {%youtube uAKzFhE3rxU %} --> ## Dependencies ## Project Structure ```>> ./NPGG ├── dist └── ... ├── node_module └── ... ├── graphql // API Schema ├── auth.graphql ├── user.graphql └── post.graphql ├── prisma // prisma schema && migrate ├──migrations // 不可以更動要且用Git追蹤 ├── __date__migration_name └── migration_name.sql └── migration.toml ├── schema.prisma // DB Schema ├── seed.ts // Data seeding └── dev.db ├── src ├── Common ├── configs/ ├── decorators/ ├── filters/ ├── interceptors/ ├── middlewares/ ├── orders/ ├── paginations/ └── models/ ├── Auth ├── Dto/ ├── Model/ ├── auth.model.ts └── token.model.ts ├── Strategy/ └── jwt.strategy.ts ├── Guard/ └── gql-auth.guard.ts ├── auth.module.ts ├── auth.resolver.ts ├── auth.service.ts └── password.service.ts // hash and compare ├── User/ ├── Post/ ├── app.module.ts ├── app.resolver.ts ├── app.service.ts ├── gql-config.service.ts ├── main.ts └── schema.graphql // API Object schema ├── test/ ├── .env ├── .gitignore ├── .dockerignore ├── .graphqlconfig ├── docker-compose.yml ├── Dockerfile ├── Dockerfile.alpine ├── package.json ├── package-lock.json └── tsconfig.json ``` ## AUTH Model & JWT Model ### Model ```>> >> base.model.ts export abstract class BaseModel{ id: string; createdAt: Date; updatedAt: Date; } >> user.model.ts export class User extends BaseModel { email: string; firstname?: string; lastname?: string; role: Role; // Custom Scale/Type posts: Post[]; // Custom Scale/Type password: string; // Must encrypt } >> token.model.ts export class Token{ accessToken: string; refreshToken: string; } >> auth.model.ts export class Auth extends Tokens{ user: User; } ``` ## Access & Refresh Token ### Service ```>> >> password.service.ts export class PasswordService{ get bcryptSaltRounds(): string | number { const securityConfig = 取得Config (ENV) const saltOrRounds = 取得 Config中 saltOrRounds Parts // 轉換成 Number return Number.isInteger(Number(saltOrRounds)) ? Number(saltOrRounds) : saltOrRounds; } constructor(private configService: ConfigService) {} validatePassword(password, hashedPassword) { // Boolean return bcrypt.compare(password, hashedPassword) } hashPassword(password): Promise<string> { // String return hash(password, this.bcryptSaltRounds) } } >> auth.service.ts export class AuthService { constructor( jwtService, prisma ) {} } ``` ### bcrypt Hash ![](https://i.imgur.com/QyAB42E.png) #### Salt Round > Means "Cost factor" >> Cost Factor controll how many times is needed to calculate a single BCrypt hash > 定義一個加密資料 需要經過幾次的Hash >> 不同的次數 也會導致同樣資料的結果不同 > 用以對抗與防禦 Rainbow Table Attacks(彩虹表攻擊)