Vla*_*kov 4 node.js typescript typeorm nestjs
我想从返回的JSON中排除密码字段。我正在使用NestJS和Typeorm。
针对此问题提供的解决方案不适用于我或NestJS。如果需要,我可以发布我的代码。还有其他想法或解决方案吗?谢谢。
Fra*_*ále 26
您可以像这样覆盖模型的 toJSON 方法。
@Entity()
export class User extends BaseAbstractEntity implements IUser {
static passwordMinLength: number = 7;
@ApiModelProperty({ example: faker.internet.email() })
@IsEmail()
@Column({ unique: true })
email: string;
@IsOptional()
@IsString()
@MinLength(User.passwordMinLength)
@Exclude({ toPlainOnly: true })
@Column({ select: false })
password: string;
@IsOptional()
@IsString()
@Exclude({ toPlainOnly: true })
@Column({ select: false })
passwordSalt: string;
toJSON() {
return classToPlain(this);
}
validatePassword(password: string) {
if (!this.password || !this.passwordSalt) {
return false;
}
return comparedToHashed(password, this.password, this.passwordSalt);
}
}
Run Code Online (Sandbox Code Playgroud)
通过使用 plainToClass 的 class-transformer 方法和@Exclude({ toPlainOnly: true }),密码将从 JSON 响应中排除,但在模型实例中可用。我喜欢这个解决方案,因为它保留了实体中的所有模型配置。
Kim*_*ern 22
作为卡米尔回答的补充:
您现在可以使用内置的ClassSerializerInterceptor,而不是创建自己的拦截器,请参阅序列化文档。
@UseInterceptors(ClassSerializerInterceptor)
Run Code Online (Sandbox Code Playgroud)
您可以在控制器类或其各个方法上使用它。这种方法返回的每个实体都将使用 class-transformer 进行转换,因此将@Exclude注释考虑在内:
import { Exclude } from 'class-transformer';
export class User {
/** other properties */
@Exclude()
password: string;
}
Run Code Online (Sandbox Code Playgroud)
您可以通过@SerializeOptions()在控制器或其方法上定义来自定义其行为:
@SerializeOptions({
excludePrefixes: ['_'],
groups: ['admin']
})
Run Code Online (Sandbox Code Playgroud)
例如,仅向某些用户公开某些字段:
@Expose({ groups: ["admin"] })
adminInfo: string;
Run Code Online (Sandbox Code Playgroud)
这个线程中有很多很好的答案。以上面 apun 的回答为基础,我认为以下方法最不可能意外泄露密码字段:
@Column({ select: false })
password: string
Run Code Online (Sandbox Code Playgroud)
如果实体默认不选择该字段,并且只能显式查询(例如,通过addSelect()使用查询构建器),我认为某处存在错误的可能性要小得多,并且对“框架(最终是class-transformer库)的魔法”以确保安全性。实际上,在许多项目中,您唯一明确选择它的地方就是您检查凭据的地方。
这种方法还可以帮助防止密码哈希意外泄漏到日志条目等中,这是尚未提及的考虑因素。在知道它不包含敏感信息的用户对象周围折腾感觉更安全,特别是如果它最终可能会在某个日志条目中被序列化。
总而言之,NestJS 的文档化方法是使用@Exclude()装饰器,并且接受的答案来自项目的创始人。
我肯定经常使用Exclude()装饰器,但不一定用于密码或盐字段。
我建议创建一个利用class-transformer库的拦截器:
@Injectable()
export class TransformInterceptor implements NestInterceptor {
intercept(
context: ExecutionContext,
call$: Observable<any>,
): Observable<any> {
return call$.pipe(map(data => classToPlain(data)));
}
}
Run Code Online (Sandbox Code Playgroud)
然后,只需使用@Exclude()装饰器排除属性,例如:
import { Exclude } from 'class-transformer';
export class User {
id: number;
email: string;
@Exclude()
password: string;
}
Run Code Online (Sandbox Code Playgroud)
@Column({ select: false })
password: string
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5084 次 |
| 最近记录: |