暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

asp.net core 腾讯验证码的接入

amazingdotnet 2019-10-20
236

asp.net core 腾讯验证码的接入

Intro

之前使用的验证码服务是用的极验验证,而且是比较旧的,好久之前接入的,而且验证码服务依赖 Session,有点不太灵活,后来发现腾讯也有验证码服务,而且支持小程序,并且是唯一支持小程序的验证码。。(垄断么。。)

而且相比之下,腾讯验证码不需要依赖 Session,集成起来也比较方便,于是就用了腾讯验证码,详细参考:https://007.qq.com/product.html?ADTAG=index.block

验证流程

服务器端接入

  1. using System.ComponentModel.DataAnnotations;

  2. using System.Net.Http;

  3. using System.Threading.Tasks;

  4. using Microsoft.Extensions.Logging;

  5. using Microsoft.Extensions.Options;

  6. using Newtonsoft.Json;

  7. using WeihanLi.Extensions;


  8. namespace ActivityReservation.Common

  9. {

  10. public class TencentCaptchaOptions

  11. {

  12. /// <summary>

  13. /// 客户端AppId

  14. /// </summary>

  15. [Required]

  16. public string AppId { get; set; }


  17. /// <summary>

  18. /// App Secret Key

  19. /// </summary>

  20. [Required]

  21. public string AppSecret { get; set; }

  22. }


  23. public class TencentCaptchaRequest

  24. {

  25. /// <summary>

  26. /// 验证码客户端验证回调的票据

  27. /// </summary>

  28. public string Ticket { get; set; }


  29. /// <summary>

  30. /// 验证码客户端验证回调的随机串

  31. /// </summary>

  32. public string Nonce { get; set; }


  33. /// <summary>

  34. /// 提交验证的用户的IP地址(eg: 10.127.10.2)

  35. /// </summary>

  36. public string UserIP { get; set; }

  37. }


  38. public class TencentCaptchaHelper

  39. {

  40. private class TencentCaptchaResponse

  41. {

  42. /// <summary>

  43. /// 1:验证成功,0:验证失败,100:AppSecretKey参数校验错误

  44. /// </summary>

  45. [JsonProperty("response")]

  46. public int Code { get; set; }


  47. /// <summary>

  48. /// 恶意等级 [0, 100]

  49. /// </summary>

  50. [JsonProperty("evil_level")]

  51. public string EvilLevel { get; set; }


  52. /// <summary>

  53. /// 错误信息

  54. /// </summary>

  55. [JsonProperty("err_msg")]

  56. public string ErrorMsg { get; set; }

  57. }


  58. private const string TencentCaptchaVerifyUrl = "https://ssl.captcha.qq.com/ticket/verify";

  59. private readonly TencentCaptchaOptions _captchaOptions;

  60. private readonly ILogger _logger;

  61. private readonly HttpClient _httpClient;


  62. public TencentCaptchaHelper(

  63. IOptions<TencentCaptchaOptions> option,

  64. ILogger<TencentCaptchaHelper> logger,

  65. HttpClient httpClient)

  66. {

  67. _captchaOptions = option.Value;

  68. _logger = logger;

  69. _httpClient = httpClient;

  70. }


  71. public async Task<bool> IsValidRequestAsync(TencentCaptchaRequest request)

  72. {

  73. // 参考文档:https://007.qq.com/captcha/#/gettingStart

  74. var response = await _httpClient.GetAsync(

  75. $"{TencentCaptchaVerifyUrl}?aid={_captchaOptions.AppId}&AppSecretKey={_captchaOptions.AppSecret}&Ticket={request.Ticket}&Randstr={request.Nonce}&UserIP={request.UserIP}");

  76. var responseText = await response.Content.ReadAsStringAsync();

  77. if (responseText.IsNotNullOrEmpty())

  78. {

  79. _logger.Debug($"Tencent captcha verify response:{responseText}");

  80. var result = responseText.JsonToType<TencentCaptchaResponse>();

  81. if (result.Code == 1)

  82. {

  83. return true;

  84. }

  85. }

  86. return false;

  87. }

  88. }

  89. }

Startup 配置:

  1. services.AddHttpClient<TencentCaptchaHelper>(client => client.Timeout = TimeSpan.FromSeconds(3))

  2. .ConfigurePrimaryHttpMessageHandler(() => new NoProxyHttpClientHandler());

  3. services.AddTencentCaptchaHelper(options =>

  4. {

  5. options.AppId = Configuration["Tencent:Captcha:AppId"];

  6. options.AppSecret = Configuration["Tencent:Captcha:AppSecret"];

  7. });

前端接入

前端接入这里不作多介绍了,接入方式多种多样,具体可以参考官方文档:https://cloud.tencent.com/document/product/1110/36841

下面的代码是 angular spa 在前端接入的核心代码

  1. private loadCaptcha(): void {

  2. var tCaptcha = document.getElementById("tCaptcha");

  3. if (tCaptcha) {

  4. this.InitCaptcha();

  5. return;

  6. }

  7. let script = <any>document.createElement('script');

  8. script.id = "tCaptcha";

  9. script.type = 'text/javascript';

  10. script.src = "https://ssl.captcha.qq.com/TCaptcha.js"

  11. if (script.readyState) { //IE

  12. script.onreadystatechange = () => {

  13. if (script.readyState === "loaded" || script.readyState === "complete") {

  14. this.InitCaptcha();

  15. }

  16. };

  17. } else { //Others

  18. script.onload = () => {

  19. this.InitCaptcha();

  20. };

  21. }

  22. document.getElementsByTagName('body')[0].appendChild(script);

  23. }


  24. private InitCaptcha(): void {

  25. let captchaDom = document.getElementById('TencentCaptcha1');

  26. if (!captchaDom) {

  27. return;

  28. }

  29. this.tencentRecaptcha = new TencentCaptcha(

  30. captchaDom, appId, (res) => {

  31. this.captchaValid = false;

  32. console.log(res);

  33. // res(用户主动关闭验证码)= {ret: 2, ticket: null}

  34. // res(验证成功) = {ret: 0, ticket: "String", randstr: "String"}

  35. if (res.ret === 0) {

  36. this.captchaInfo.nonce = res.randstr;

  37. this.captchaInfo.ticket = res.ticket;

  38. this.captchaValid = true;

  39. this.tencentRecaptcha.destroy();


  40. let button = <HTMLElement>document.getElementById("btnSubmit");

  41. button.click();

  42. }

  43. }

  44. );

  45. console.log(`captcha inited`);

  46. this.tencentRecaptcha.show();

  47. }

使用效果:

老版网站接入效果:

Reference

  • https://github.com/WeihanLi/ActivityReservation

  • https://reservation.weihanli.xyz/Home/Reservate

  • https://reservation-client.weihanli.xyz/reservation/new

  • https://cloud.tencent.com/document/product/1110/36841


文章转载自amazingdotnet,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论