Nestjs 和 Google Recaptcha
Nestjs and Google Recaptcha
我正在尝试使用 Nestjs 为 reCaptcha 实现服务器端验证,我想我是否应该将其实现为模块或模块服务(例如自写的用户身份验证模块),这将需要reCaptcha 的使用。
导入HttpModule
import { Module } from '@nestjs/common';
import { HttpModule } from "@nestjs/axios";
@Module({
imports: [HttpModule],
...
})
然后创建一个服务来验证验证码值
注意:您必须从 here 获取 secret/site 密钥(站点密钥将在客户端中使用)
import { HttpService, Inject, Injectable } from "@nestjs/common";
import { REQUEST } from '@nestjs/core';
import { Request } from 'express';
import { map } from 'rxjs/operators'
@Injectable()
export class CaptchaService {
constructor(
@Inject(REQUEST) private readonly request: Request,
private httpService: HttpService) { }
public validate(value:string): Promise<any> {
const remoteAddress = this.request.socket.remoteAddress
const secretKey = "XXXXXXXXX"
const url = "https://www.google.com/recaptcha/api/siteverify?secret=" + secretKey + "&response=" + value + "&remoteip=" + remoteAddress;
return this.httpService.post(url).pipe(map(response => {
return response['data']
})).toPromise()
}
}
然后在你的控制器中:
const value="XXXXX" // client send this for you
const result = await this.captchService.validate(value)
if (!result.success) throw new BadRequestException()
客户端
如果您使用 angular,您可以使用 this
我通过创建一个单独的 Recaptcha Guard 解决了这个问题。
// recaptcha.guard.ts
import {
Injectable,
CanActivate,
ExecutionContext,
HttpService,
ForbiddenException,
} from "@nestjs/common";
@Injectable()
export class RecaptchaGuard implements CanActivate {
constructor(private readonly httpService: HttpService) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const { body } = context.switchToHttp().getRequest();
const { data } = await this.httpService
.post(
`https://www.google.com/recaptcha/api/siteverify?response=${body.recaptchaValue}&secret=${process.env.RECAPTCHA_SECRET}`
)
.toPromise();
if (!data.success) {
throw new ForbiddenException();
}
return true;
}
}
接下来您可以简单地在控制器上应用 recaptcha 防护。
// app.controller.ts
import { Controller, Post, UseGuard } from '@nestjs/common';
import { RecaptchaGuard } from './recaptcha.guard.ts'
@Controller()
export class AppController {
@Post()
@UseGuard(RecaptchaGuard)
async postForm(){
//
}
}
最初,我一直在关注已接受的答案,然后发现有一种更简单的方法 - 并且想分享它以防万一它可以帮助到任何人。
有一个 NestJS 模块可以轻松集成 ReCAPTCHA:https://github.com/chvarkov/google-recaptcha。
- 安装模块。
- 在您的
AppModule
中创建如下内容:
const googleRecaptchaFactory = (
applicationConfigService: ApplicationConfigService,
) => ({
secretKey: applicationConfigService.auth.recaptcha.secretKey,
response: (req) => req.headers.recaptcha || '',
skipIf: applicationConfigService.auth.recaptcha.bypassVerification,
});
@Module({
controllers: [/* ... */],
imports: [
/* ... */
GoogleRecaptchaModule.forRootAsync({
imports: [],
inject: [ApplicationConfigService],
useFactory: googleRecaptchaFactory,
}),
],
providers: [/* ... */],
exports: [/* ... */],
})
export class Module {}
- 现在,在你的控制器中,使用
@Recapcha
守卫。
您可以在链接 Github 中找到整个集成过程的文档。
我正在尝试使用 Nestjs 为 reCaptcha 实现服务器端验证,我想我是否应该将其实现为模块或模块服务(例如自写的用户身份验证模块),这将需要reCaptcha 的使用。
导入HttpModule
import { Module } from '@nestjs/common';
import { HttpModule } from "@nestjs/axios";
@Module({
imports: [HttpModule],
...
})
然后创建一个服务来验证验证码值
注意:您必须从 here 获取 secret/site 密钥(站点密钥将在客户端中使用)
import { HttpService, Inject, Injectable } from "@nestjs/common";
import { REQUEST } from '@nestjs/core';
import { Request } from 'express';
import { map } from 'rxjs/operators'
@Injectable()
export class CaptchaService {
constructor(
@Inject(REQUEST) private readonly request: Request,
private httpService: HttpService) { }
public validate(value:string): Promise<any> {
const remoteAddress = this.request.socket.remoteAddress
const secretKey = "XXXXXXXXX"
const url = "https://www.google.com/recaptcha/api/siteverify?secret=" + secretKey + "&response=" + value + "&remoteip=" + remoteAddress;
return this.httpService.post(url).pipe(map(response => {
return response['data']
})).toPromise()
}
}
然后在你的控制器中:
const value="XXXXX" // client send this for you
const result = await this.captchService.validate(value)
if (!result.success) throw new BadRequestException()
客户端
如果您使用 angular,您可以使用 this
我通过创建一个单独的 Recaptcha Guard 解决了这个问题。
// recaptcha.guard.ts
import {
Injectable,
CanActivate,
ExecutionContext,
HttpService,
ForbiddenException,
} from "@nestjs/common";
@Injectable()
export class RecaptchaGuard implements CanActivate {
constructor(private readonly httpService: HttpService) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const { body } = context.switchToHttp().getRequest();
const { data } = await this.httpService
.post(
`https://www.google.com/recaptcha/api/siteverify?response=${body.recaptchaValue}&secret=${process.env.RECAPTCHA_SECRET}`
)
.toPromise();
if (!data.success) {
throw new ForbiddenException();
}
return true;
}
}
接下来您可以简单地在控制器上应用 recaptcha 防护。
// app.controller.ts
import { Controller, Post, UseGuard } from '@nestjs/common';
import { RecaptchaGuard } from './recaptcha.guard.ts'
@Controller()
export class AppController {
@Post()
@UseGuard(RecaptchaGuard)
async postForm(){
//
}
}
最初,我一直在关注已接受的答案,然后发现有一种更简单的方法 - 并且想分享它以防万一它可以帮助到任何人。
有一个 NestJS 模块可以轻松集成 ReCAPTCHA:https://github.com/chvarkov/google-recaptcha。
- 安装模块。
- 在您的
AppModule
中创建如下内容:
const googleRecaptchaFactory = (
applicationConfigService: ApplicationConfigService,
) => ({
secretKey: applicationConfigService.auth.recaptcha.secretKey,
response: (req) => req.headers.recaptcha || '',
skipIf: applicationConfigService.auth.recaptcha.bypassVerification,
});
@Module({
controllers: [/* ... */],
imports: [
/* ... */
GoogleRecaptchaModule.forRootAsync({
imports: [],
inject: [ApplicationConfigService],
useFactory: googleRecaptchaFactory,
}),
],
providers: [/* ... */],
exports: [/* ... */],
})
export class Module {}
- 现在,在你的控制器中,使用
@Recapcha
守卫。
您可以在链接 Github 中找到整个集成过程的文档。