---
# System prepended metadata

title: NestJS & Passport & JWT
tags: [NestJS, JWT, Passport, bcrypt]

---

#    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(彩虹表攻擊)