在构建网站时,经常面临一个挑战:如何有效减少垃圾邮件的侵扰。本文将介绍如何通过使用SendGrid和Google reCaptcha来实现这一目标。SendGrid是一个流行的邮件发送服务,而Google reCaptcha则是一种广泛使用的验证工具,可以有效防止自动化的垃圾邮件提交。
SendGrid提供了一个免费计划,允许每天发送多达100封邮件,这对于小型网站来说已经足够。如果需要发送更多邮件,可以选择升级到付费计划,或者切换回自己的SMTP服务器。首先,需要访问创建账户,然后获取SendGrid API密钥,用于通过API发送邮件。
要设置Google reCaptcha,需要有一个Google账户。设置v2版本的reCaptcha,并将本地主机(用于本地开发测试)、域名以及部署在Azure上的域名添加到有效域名列表中。Google会提供两个客户端代码片段:一个是引用JavaScript库的代码,另一个是包含reCaptcha的div元素。同时,还会得到一个服务器端密钥,用于在验证reCaptcha时调用。
在Razor页面中,创建了一个名为ContactFormModel的类,用于将用户输入的邮件详情传递到服务器,并使用属性帮助显示和验证邮件详情。注入了IConfiguration来读取appsettings.json中的值,注入了IHttpClientFactory来创建HTTP客户端,以及注入了ILogger来记录调试信息。
public class ContactFormModel
{
[Required]
[StringLength(50)]
public string Name { get; set; }
[Required]
[StringLength(255)]
[EmailAddress]
public string Email { get; set; }
[Required]
[StringLength(1000)]
public string Message { get; set; }
}
public class ContactModel : PageModel
{
[BindProperty]
public ContactFormModel Contact { get; set; }
private readonly IConfiguration _configuration;
private readonly IHttpClientFactory _httpClientFactory;
private readonly ILogger _logger;
public ContactModel(IConfiguration configuration,
IHttpClientFactory httpClientFactory,
ILogger logger)
{
_configuration = configuration;
_httpClientFactory = httpClientFactory;
_logger = logger;
}
private bool RecaptchaPassed(string recaptchaResponse)
{
var secret = _configuration.GetSection("RecaptchaKey").Value;
var endPoint = _configuration.GetSection("RecaptchaEndPoint").Value;
var googleCheckUrl = $"{endPoint}?secret={secret}&response={recaptchaResponse}";
var httpClient = _httpClientFactory.CreateClient();
var response = httpClient.GetAsync(googleCheckUrl).Result;
if (!response.IsSuccessStatusCode)
{
return false;
}
dynamic jsonData = JObject.Parse(response.Content.ReadAsStringAsync().Result);
return (jsonData.success == "true");
}
public async Task OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
var gRecaptchaResponse = Request.Form["g-recaptcha-response"];
if (string.IsNullOrEmpty(gRecaptchaResponse) || !RecaptchaPassed(gRecaptchaResponse))
{
ModelState.AddModelError(string.Empty, "You failed the CAPTCHA");
return Page();
}
var from = new EmailAddress(Contact.Email, Contact.Name);
var to = new EmailAddress(_configuration.GetSection("ContactUsMailbox").Value);
const string subject = "Website Contact Us Message";
var apiKey = _configuration.GetSection("SENDGRID_API_KEY").Value;
var client = new SendGridClient(apiKey);
var msg = MailHelper.CreateSingleEmail(from, to, subject, Contact.Message, WebUtility.HtmlEncode(Contact.Message));
var response = await client.SendEmailAsync(msg);
if (response.StatusCode != HttpStatusCode.Accepted)
{
throw new ExternalException("Error sending message");
}
return RedirectToPage("Index");
}
}
在Razor页面的标记中,设置了模型为ContactModel,并在@section Scripts中包含了Google reCaptcha的JavaScript库。reCaptcha的div元素被包含在提交按钮之前。
@page
@model MainWebsite.Pages.ContactModel
@{
ViewData["Title"] = "Contact Us";
}
@section Scripts
{
}
在appsettings.json文件中,需要包含SendGrid API密钥、接收邮件的邮箱地址、reCaptcha密钥和验证端点。
"SENDGRID_API_KEY": "enter your sendgrid api key here",
"ContactUsMailbox": "enter email address you want mail sent to here",
"RecaptchaKey": "enter your recaptcha key here",
"RecaptchaEndPoint": "https://www.google.com/recaptcha/api/siteverify"
在Startup.cs的ConfigureServices方法中,需要添加以下代码行以确保IHttpClientFactory可用于注入。
services.AddHttpClient();