public async Task <BlogResponse <string> > GenerateAsync(GenerateSignatureInput input) { return(await _cache.GenerateAsync(input, async() => { var response = new BlogResponse <string>(); var ip = _httpContextAccessor.HttpContext.Request.Headers["X-Real-IP"].FirstOrDefault() ?? _httpContextAccessor.HttpContext.Request.Headers["X-Forwarded-For"].FirstOrDefault() ?? _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString(); var type = Signature.KnownTypes.Dictionary.FirstOrDefault(x => x.Value == input.TypeId).Key; if (type.IsNullOrEmpty()) { response.IsFailed($"The signature type not exists."); return response; } var signature = await _signatures.FindAsync(x => x.Name == input.Name && x.Type == type); if (signature is not null) { response.Result = signature.Url; return response; } var api = _signatureOptions.Urls .OrderBy(x => GuidGenerator.Create()) .Select(x => new { Url = x.Key, Param = string.Format(x.Value, input.Name, input.TypeId) }) .FirstOrDefault(); var content = new StringContent(api.Param); content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded"); using var client = _httpClient.CreateClient(); client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0"); var httpResponse = await client.PostAsync(api.Url, content); var httpResult = await httpResponse.Content.ReadAsStringAsync(); var regex = new Regex(@"<img\b[^<>]*?\bsrc[\s\t\r\n]*=[\s\t\r\n]*[""']?[\s\t\r\n]*(?<imgUrl>[^\s\t\r\n""'<>]*)[^<>]*?/?[\s\t\r\n]*>", RegexOptions.IgnoreCase); var imgUrl = regex.Match(httpResult).Groups["imgUrl"].Value; var url = $"{$"{input.Name}_{type}".ToMd5()}.png"; var signaturePath = Path.Combine(_signatureOptions.Path, url); var imgBuffer = await client.GetByteArrayAsync(imgUrl); await imgBuffer.DownloadAsync(signaturePath); await _signatures.InsertAsync(new Signature { Name = input.Name, Type = type, Url = url, Ip = ip }); response.Result = url; return response; }));
/// <summary> /// 生成个性艺术签名 /// </summary> /// <param name="input"></param> /// <param name="factory"></param> /// <returns></returns> public async Task <ServiceResult <string> > GenerateSignatureAsync(GenerateSignatureInput input, Func <Task <ServiceResult <string> > > factory) { return(await Cache.GetOrAddAsync(KEY_GenerateSignature.FormatWith(input.Name, input.Id), factory, CacheStrategy.ONE_HOURS)); }
/// <summary> /// 生成个性艺术签名 /// </summary> /// <param name="input"></param> /// <returns></returns> public async Task <ServiceResult <string> > GenerateSignatureAsync(GenerateSignatureInput input) { var result = new ServiceResult <string>(); var ip = _httpContextAccessor.HttpContext.Request.GetClientIp(); // TODO:当前ip是否在小黑屋,禁止使用 // 验签,请求是否合法 var sign = $"{input.Name}_{input.Id}_{input.Timestamp}".EncodeMd5String().ToLower(); if (input.Sign != sign) { result.IsFailed("验签不正确"); return(result); } return(await _signatureCacheService.GenerateSignatureAsync(input, async() => { // 签名类型 var type = typeof(SignatureEnum).TryToList().FirstOrDefault(x => x.Value.Equals(input.Id))?.Description; if (string.IsNullOrEmpty(type)) { result.IsFailed("签名类型不存在"); return result; } // 查询是否存在此签名,存在则直接返回 var signature = await _signatureRepository.FindAsync(x => x.Name.Equals(input.Name) && x.Type.Equals(type)); if (signature.IsNotNull()) { result.IsSuccess(signature.Url); return result; } // 签名图片名称 var signaturePicName = $"{sign}.png"; // 在配置文件中随机取一条签名api var signatureUrl = AppSettings.Signature.Urls.OrderBy(x => GuidGenerator.Create()).Select(x => new { Url = x.Key, Parameter = x.Value.FormatWith(input.Name, input.Id) }).FirstOrDefault(); // 发送请求,获取结果 var content = new StringContent(signatureUrl.Parameter); content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded"); using var client = _httpClient.CreateClient(); client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.14 Safari/537.36 Edg/83.0.478.13"); var httpResponse = await client.PostAsync(signatureUrl.Url, content); var httpResult = await httpResponse.Content.ReadAsStringAsync(); // 正则获取api返回的签名图片 var regex = new Regex(@"<img\b[^<>]*?\bsrc[\s\t\r\n]*=[\s\t\r\n]*[""']?[\s\t\r\n]*(?<imgUrl>[^\s\t\r\n""'<>]*)[^<>]*?/?[\s\t\r\n]*>", RegexOptions.IgnoreCase); var imgUrl = regex.Match(httpResult).Groups["imgUrl"].Value; // 签名保存的路径 var signaturePath = Path.Combine(AppSettings.Signature.Path, signaturePicName); // 保存图片至本地 var imgBuffer = await client.GetByteArrayAsync(imgUrl); await imgBuffer.DownloadAsync(signaturePath); // 添加水印 await signaturePath.AddWatermarkAndSaveItAsync(); // 保存调用记录 var entity = new Domain.Signature.Signature { Name = input.Name, Type = type, Url = signaturePicName, Ip = ip, CreateTime = DateTime.Now }; await _signatureRepository.InsertAsync(entity); result.IsSuccess(entity.Url); return result; }));
public async Task <ServiceResult <string> > GenerateSignatureForPostAsync([FromBody] GenerateSignatureInput input) { return(await _signatureService.GenerateSignatureAsync(input)); }
public async Task <BlogResponse <string> > GenerateAsync(GenerateSignatureInput input, Func <Task <BlogResponse <string> > > func) => await Cache.GetOrAddAsync(CachingConsts.CacheKeys.GenerateSignature(input.Name, input.TypeId), func, CachingConsts.CacheStrategy.ONE_HOURS);