我正在构建一个微服务项目,其中两个服务是:
- API Gateway:用于路由到合适的服务。
- 身份验证服务:用于验证用户凭据/用户令牌。
Authentication 服务是由 NestJS 使用 TCP 协议构建的。
例如登录:
- 从客户端到 API 网关的 HTTP 请求。API 网关发送到身份验证服务
const oAuthenticatedUser: LoginUserResponseDto = await this.authMicroServiceClient.send('login', loginRequest).toPromise()
以验证电子邮件和密码。如果用户的凭据正确,它将返回 UserInfo(名称、access_token 和 regresh_token)。
案例:create-post
- 从客户端到 API 网关的 HTTP 请求,其中 access_token 为
header
. 在调用 post-service 执行 post-creation 之前,API Gateway 调用 Authentication 服务来验证令牌const authenReponse = await this.authMicroServiceClient.send('verify_access_token', { token: access_token }).toPromise();
我的痛点:我不能在身份验证服务中使用 Passport 策略来实现通用验证令牌。因为现在对 Authentication Service 的请求已经不是普通的 HTTP 请求了。然后这些当前代码无法使用:
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { TJwtPayload } from '../../types/auth/jwt-payload.type';
import { UserSimpleDTO } from '@modules/user/dto';
import { ConfigService } from '@nestjs/config'
import { TokenService } from '@app/shared/services'
/**
* Powered Thuan
* @author thuan.nguyen
* @namespace auth
* @classname JwtAccessTokenStrategy
**/
@Injectable()
export class JwtAccessTokenStrategy extends PassportStrategy(Strategy, 'jwt-access-token') {
constructor(private readonly tokenService: TokenService, configService: ConfigService) {
super({
jwtFromRequest: ExtractJwt.fromExtractors([
ExtractJwt.fromAuthHeaderAsBearerToken(),
]),
ignoreExpiration: true,
secretOrKey: configService.get("JWT_ACCESS_SECRET"),
});
}
async validate(payload: TJwtPayload): Promise<UserSimpleDTO> {
const user = await this.tokenService.validatePayload(payload);
if (!user) {
throw new UnauthorizedException('Cannot find user via payload');
}
return user;
}
}
和
import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { UserService } from '../user/user.service';
import { UserLoginReqDTO } from '@modules/user/dto';
/**
* Powered by Thuan
* @author thuan.nguyen
* @namespace auth
* @classname LocalStrategy
**/
@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
constructor(
private userService: UserService,
) {
super({ usernameField: 'email' });
}
async validate(email: string, password: string): Promise<UserLoginReqDTO> {
const user: UserLoginReqDTO = await this.userService.getUserIfPasswordMatches(email, password);
if (!user) {
throw new UnauthorizedException();
}
return user;
}
}
我的问题是:我的设计好不好。我想知道更好的设计。以及如何将上述代码用于通过 TCP 协议传输的请求。
谢谢!