初始化:职引项目 v1.0
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
import { createParamDecorator, ExecutionContext } from '@nestjs/common'
|
||||
|
||||
export const CurrentUser = createParamDecorator(
|
||||
(data: string | undefined, ctx: ExecutionContext) => {
|
||||
const request = ctx.switchToHttp().getRequest()
|
||||
const user = request.user
|
||||
return data ? user?.[data] : user
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,3 @@
|
||||
import { SetMetadata } from '@nestjs/common'
|
||||
export const IS_PUBLIC_KEY = 'isPublic'
|
||||
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true)
|
||||
@@ -0,0 +1,40 @@
|
||||
import { ExceptionFilter, Catch, ArgumentsHost, HttpException, HttpStatus, Logger } from '@nestjs/common';
|
||||
import { Request, Response } from 'express';
|
||||
|
||||
@Catch()
|
||||
export class AllExceptionsFilter implements ExceptionFilter {
|
||||
private readonly logger = new Logger(AllExceptionsFilter.name);
|
||||
|
||||
catch(exception: unknown, host: ArgumentsHost) {
|
||||
const ctx = host.switchToHttp();
|
||||
const response = ctx.getResponse<Response>();
|
||||
const request = ctx.getRequest<Request>();
|
||||
|
||||
const status = exception instanceof HttpException
|
||||
? exception.getStatus()
|
||||
: HttpStatus.INTERNAL_SERVER_ERROR;
|
||||
|
||||
const message = exception instanceof HttpException
|
||||
? exception.getResponse()
|
||||
: '服务器内部错误';
|
||||
|
||||
const errorResponse = {
|
||||
code: status,
|
||||
message: typeof message === 'string' ? message : (message as any).message || message,
|
||||
timestamp: new Date().toISOString(),
|
||||
path: request.url,
|
||||
};
|
||||
|
||||
// 记录错误日志
|
||||
if (status >= 500) {
|
||||
this.logger.error(
|
||||
`Internal error: ${request.method} ${request.url}`,
|
||||
exception instanceof Error ? exception.stack : String(exception),
|
||||
);
|
||||
} else if (status >= 400) {
|
||||
this.logger.warn(`Client error: ${request.method} ${request.url} - ${JSON.stringify(errorResponse)}`);
|
||||
}
|
||||
|
||||
response.status(status).json(errorResponse);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { Injectable, ExecutionContext } from '@nestjs/common'
|
||||
import { AuthGuard } from '@nestjs/passport'
|
||||
import { Reflector } from '@nestjs/core'
|
||||
import { IS_PUBLIC_KEY } from '../decorators/public.decorator'
|
||||
|
||||
@Injectable()
|
||||
export class JwtAuthGuard extends AuthGuard('jwt') {
|
||||
constructor(private reflector: Reflector) {
|
||||
super()
|
||||
}
|
||||
|
||||
canActivate(context: ExecutionContext) {
|
||||
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
|
||||
context.getHandler(),
|
||||
context.getClass(),
|
||||
])
|
||||
if (isPublic) return true
|
||||
return super.canActivate(context)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { PassportStrategy } from '@nestjs/passport'
|
||||
import { ExtractJwt, Strategy } from 'passport-jwt'
|
||||
|
||||
@Injectable()
|
||||
export class JwtStrategy extends PassportStrategy(Strategy) {
|
||||
constructor() {
|
||||
super({
|
||||
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
||||
ignoreExpiration: false,
|
||||
secretOrKey: process.env.JWT_SECRET || 'zhiyin-jwt-secret-2026',
|
||||
})
|
||||
}
|
||||
|
||||
async validate(payload: { userId: string; phone: string }) {
|
||||
return { userId: payload.userId, phone: payload.phone }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user