diff --git a/apps/talk/src/app.module.ts b/apps/talk/src/app.module.ts index 61f286e..9f59bd2 100644 --- a/apps/talk/src/app.module.ts +++ b/apps/talk/src/app.module.ts @@ -1,9 +1,8 @@ import { Global, Logger, Module, ValidationPipe } from "@nestjs/common"; -import { APP_FILTER, APP_PIPE } from "@nestjs/core"; +import { APP_PIPE } from "@nestjs/core"; import { ConfigModule } from "./common/config/config.module"; import { database } from "./config/database.config"; -import { AppFilter } from "./filters/app.filter"; import { Env } from "./modules/config/env"; import { DatabaseModule } from "./modules/database/database.module"; import { UserModule } from "./modules/user/user.module"; @@ -31,10 +30,10 @@ import { UserModule } from "./modules/user/user.module"; provide: APP_PIPE, useClass: ValidationPipe, }, - { - provide: APP_FILTER, - useClass: AppFilter, - }, + // { + // provide: APP_FILTER, + // useClass: AppFilter, + // }, ], }) export class AppModule { diff --git a/apps/talk/src/main.ts b/apps/talk/src/main.ts index 287ff38..26ef43b 100644 --- a/apps/talk/src/main.ts +++ b/apps/talk/src/main.ts @@ -4,12 +4,8 @@ import { useContainer } from "class-validator"; import { WinstonModule } from "nest-winston"; import { AppModule } from "./app.module"; -import { findup } from "./modules/config/findup"; import { instance } from "./until/winstonconfig"; -const envFile = findup(".env"); -console.log(envFile); - async function bootstrap() { const app = await NestFactory.create(AppModule, { logger: WinstonModule.createLogger({ instance }), diff --git a/apps/talk/src/modules/database/database.module.ts b/apps/talk/src/modules/database/database.module.ts index 1919670..862a021 100644 --- a/apps/talk/src/modules/database/database.module.ts +++ b/apps/talk/src/modules/database/database.module.ts @@ -1,12 +1,11 @@ import type { DynamicModule, ModuleMetadata } from "@nestjs/common"; import type { TypeOrmModuleOptions } from "@nestjs/typeorm"; -import { Global, Module } from "@nestjs/common"; +import { Module } from "@nestjs/common"; import { TypeOrmModule } from "@nestjs/typeorm"; import { UniqueConstraint } from "../user/constraints/unique.constraint"; -@Global() @Module({}) export class DatabaseModule { static forRoot(config: TypeOrmModuleOptions): DynamicModule { diff --git a/apps/talk/src/modules/user/controller/user.controller.ts b/apps/talk/src/modules/user/controller/user.controller.ts index 63d7c62..f097f32 100644 --- a/apps/talk/src/modules/user/controller/user.controller.ts +++ b/apps/talk/src/modules/user/controller/user.controller.ts @@ -1,19 +1,26 @@ import { Body, Controller, Get, Post, SerializeOptions } from "@nestjs/common"; -import { CreateUserDto } from "../dtos/user.dto"; import { UserEntity } from "../entities/user.entity"; +import { TokenService } from "../services/token.service"; import { UserService } from "../services/user.service"; @Controller("users") export class UserController { - constructor(private readonly service: UserService) {} + constructor( + private readonly service: UserService, + private tokenService: TokenService, + ) {} @Get("/") async index() { - return UserEntity.find(); + const user = (await UserEntity.findOne({ + where: { id: "9d412d99-c725-4c9f-a555-3dd88bd607d6" }, + })) as UserEntity; + const now = Number(new Date()); + return this.tokenService.generateToken(user, now); } @Post("/") @SerializeOptions({}) - async create(@Body() data: CreateUserDto) { - return this.service.create(data); + async create(@Body() data: any) { + return this.tokenService.verifyAccessToken(data.token); } } diff --git a/apps/talk/src/modules/user/services/test.ts b/apps/talk/src/modules/user/services/test.ts new file mode 100644 index 0000000..2fdb081 --- /dev/null +++ b/apps/talk/src/modules/user/services/test.ts @@ -0,0 +1,6 @@ +import { UserEntity } from "../entities/user.entity"; + +const user = UserEntity.findOne({ + where: { id: "9d412d99-c725-4c9f-a555-3dd88bd607d6" }, +}); +console.log(user); diff --git a/apps/talk/src/modules/user/services/token.service.ts b/apps/talk/src/modules/user/services/token.service.ts index 25aa10b..cb07b04 100644 --- a/apps/talk/src/modules/user/services/token.service.ts +++ b/apps/talk/src/modules/user/services/token.service.ts @@ -1,6 +1,8 @@ import { Injectable } from "@nestjs/common"; import { JwtService } from "@nestjs/jwt"; -import dayjs from "dayjs"; +import { InjectRepository } from "@nestjs/typeorm"; +import { Response } from "express"; +import { Repository } from "typeorm"; import { v7 } from "uuid"; import { AccessTokenEntity } from "../entities/access-token.entity"; @@ -11,32 +13,52 @@ import { JwtConfig, JwtPayload } from "../types"; @Injectable() export class TokenService { private config: JwtConfig = { - token_expired: 60, - refresh_token_expired: 60 * 24 * 7, + token_expired: 60 * 60, + refresh_token_expired: 60 * 60 * 24 * 7, }; private access_secret = "hTVLuGqhuKZW9HUnKzs83yvVBitlwc5d0PNfJqDRsRs="; - constructor(protected jwtService: JwtService) {} + constructor( + protected jwtService: JwtService, + @InjectRepository(AccessTokenEntity) + protected accesTokenRepository: Repository, + @InjectRepository(RefreshTokenEntity) + protected refreshaccesTokenRepository: Repository, + ) {} + + async refreshToken(accesToken: AccessTokenEntity, response: Response) { + const { user, refreshToken } = accesToken; + if (refreshToken) { + const now = Number(new Date()); + if (now < Number(refreshToken.expired_at)) return null; + const token = await this.generateToken(user, now); + await accesToken.remove(); + response.header("token", token.accessToken.value); + return token; + } + return null; + } // Generate access token - async generateToken(user: UserEntity, now: dayjs.Dayjs) { + // 生成accesstoken的时候,生成refresh token + async generateToken(user: UserEntity, now: number) { const accessTokenPayload: JwtPayload = { sub: user.id, - iat: now.unix(), + iat: now, }; - const signed = this.jwtService.sign(accessTokenPayload); + const signed = this.jwtService.sign(accessTokenPayload, { + secret: this.access_secret, + }); const accessToken = new AccessTokenEntity(); accessToken.value = signed; accessToken.user = user; - accessToken.expired_at = now - .add(this.config.token_expired, "second") - .toDate(); - await accessToken.save(); + accessToken.expired_at = new Date(now + this.config.token_expired * 1000); + await this.accesTokenRepository.save(accessToken); const refreshToken = await this.generateRefreshToken(accessToken, now); return { accessToken, refreshToken }; } - async generateRefreshToken(accessToken: AccessTokenEntity, now: dayjs.Dayjs) { + async generateRefreshToken(accessToken: AccessTokenEntity, now: number) { const refreshTokenPayload = { uuid: v7(), }; @@ -45,17 +67,14 @@ export class TokenService { secret: this.access_secret, }); refreshToken.accessToken = accessToken; - refreshToken.expired_at = now - .add(this.config.refresh_token_expired, "second") - .toDate(); + refreshToken.expired_at = new Date( + now + this.config.refresh_token_expired * 1000, + ); await refreshToken.save(); return refreshToken; } async checkAccessToken(token: string) { - return AccessTokenEntity.findOne({ - where: { value: token }, - relations: ["user", "refreshToken"], - }); + return this.accesTokenRepository.findOne({ where: { value: token } }); } async rmAccessToken(token: string) { const accessToken = await AccessTokenEntity.findOne({ @@ -64,7 +83,9 @@ export class TokenService { accessToken && (await accessToken.remove()); } async verifyAccessToken(token: string) { - const user = await this.jwtService.verify(token, {}); + const user = await this.jwtService.verify(token, { + secret: this.access_secret, + }); return user || false; } } diff --git a/apps/talk/src/modules/user/user.module.ts b/apps/talk/src/modules/user/user.module.ts index fc0958f..8e9bba0 100644 --- a/apps/talk/src/modules/user/user.module.ts +++ b/apps/talk/src/modules/user/user.module.ts @@ -1,15 +1,28 @@ import { Module } from "@nestjs/common"; +import { JwtModule, JwtService } from "@nestjs/jwt"; import { TypeOrmModule } from "@nestjs/typeorm"; import { UniqueConstraint } from "./constraints/unique.constraint"; import { UserController } from "./controller/user.controller"; import { UserEntity } from "./entities/user.entity"; +import { TokenService } from "./services/token.service"; import { UserService } from "./services/user.service"; import { UserSubscriber } from "./subscribers/user.subscriber"; @Module({ - imports: [TypeOrmModule.forFeature([UserEntity])], - providers: [UserSubscriber, UserService, UniqueConstraint], + imports: [ + TypeOrmModule.forFeature([UserEntity]), + JwtModule.register({ + secret: "hTVLuGqhuKZW9HUnKzs83yvVBitlwc5d0PNfJqDRsRs=", + }), + ], + providers: [ + UserSubscriber, + UserService, + UniqueConstraint, + TokenService, + JwtService, + ], controllers: [UserController], exports: [], }) diff --git a/apps/talk/src/test.ts b/apps/talk/src/test.ts new file mode 100644 index 0000000..e69de29