tokenservice

master
lee 2025-05-23 16:31:58 +08:00
parent 8640838804
commit 29d886788f
8 changed files with 80 additions and 39 deletions

View File

@ -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 {

View File

@ -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 }),

View File

@ -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 {

View File

@ -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);
}
}

View File

@ -0,0 +1,6 @@
import { UserEntity } from "../entities/user.entity";
const user = UserEntity.findOne({
where: { id: "9d412d99-c725-4c9f-a555-3dd88bd607d6" },
});
console.log(user);

View File

@ -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<AccessTokenEntity>,
@InjectRepository(RefreshTokenEntity)
protected refreshaccesTokenRepository: Repository<RefreshTokenEntity>,
) {}
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;
}
}

View File

@ -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: [],
})

View File