public IActionResult TicketVerify(TicketVerifyModel ticketVerify) { TicketVerifyResponseModel responseModel = null; // appId, appSecret效验: 这通常需要你自己根据业务实现 IAppChecker AppCheckModel appCheckResult = _appChecker.Check(ticketVerify.AppId, ticketVerify.AppSecret); if (!appCheckResult.Pass) { // -7 AppId,AppSecret效验不通过 responseModel = new TicketVerifyResponseModel { code = -7, message = appCheckResult.Message }; return(Ok(responseModel)); } // ticket 效验 responseModel = _service.TicketVerify(ticketVerify.AppId, ticketVerify.AppSecret, ticketVerify.Ticket, ticketVerify.UserId, ticketVerify.UserIp); return(Ok(responseModel)); }
public override async Task InvokeAsync(HttpContext context) { string inputBody; using (var reader = new System.IO.StreamReader( context.Request.Body, Encoding.UTF8)) { inputBody = await reader.ReadToEndAsync(); } TicketVerifyModel ticketVerify = _jsonHelper.Deserialize <TicketVerifyModel>(inputBody); // ticket 效验 TicketVerifyResponseModel responseModel = _service.TicketVerify(ticketVerify.AppId, ticketVerify.AppSecret, ticketVerify.Ticket, ticketVerify.UserId, ticketVerify.UserIp); string responseJsonStr = _jsonHelper.Serialize(responseModel); context.Response.ContentType = "application/json"; await context.Response.WriteAsync(responseJsonStr, Encoding.UTF8); // Response.Write 开始, 不要再 Call next // Call the next delegate/middleware in the pipeline //await _next(context); }
/// <summary> /// 效验票据有效性 /// </summary> /// <param name="ticket">验证码客户端验证回调的票据</param> /// <param name="userId">用户会话唯一标识</param> /// <param name="userIp">提交验证的用户的IP地址(eg: 10.127.10.2)</param> /// <returns></returns> public TicketVerifyResponseModel Verify(string ticket, string userId, string userIp) { TicketVerifyResponseModel ticketVerifyModel = new TicketVerifyResponseModel { code = -1, message = "效验失败" }; string reqJsonStr = JsonHelper.Serialize(new { appId = _options.AppId, appSecret = _options.AppSecret, ticket, userId, userIp }); //string reqStr = $"appId={_options.AppId}&appSecret={_options.AppSecret}&ticket={ticket}&userId={userId}&userIp={userIp}"; // 效验票据 try { string[] headers = { "Content-Type: application/json" }; //string[] headers = { "Content-Type: application/x-www-form-urlencoded" }; string resJsonStr = HttpAide.HttpPost(_options.TicketVerifyUrl, postDataStr: reqJsonStr, headers: headers); //string resJsonStr = HttpAide.HttpPost(_options.TicketVerifyUrl, postDataStr: reqStr); ticketVerifyModel = JsonHelper.Deserialize <TicketVerifyResponseModel>(resJsonStr); } catch (Exception ex) { } return(ticketVerifyModel); }
/// <summary> /// ticket效验 /// </summary> /// <param name="appId"></param> /// <param name="appSecret"></param> /// <param name="ticket"></param> /// <param name="userId">用户唯一标识</param> /// <param name="userIp"></param> /// <param name="aesKey"></param> /// <returns></returns> public TicketVerifyResponseModel TicketVerify(string appId, string appSecret, string ticket, string userId, string userIp) { TicketVerifyResponseModel rtnResult = null; // appId, appSecret效验: 这通常需要你自己根据业务实现 IAppChecker #region AppId,AppSecret效验 AppCheckModel appCheckResult = AppChecker.Check(appId, appSecret); if (!appCheckResult.Pass) { // -7 AppId,AppSecret效验不通过 rtnResult = new TicketVerifyResponseModel { code = -7, message = appCheckResult.Message }; return(rtnResult); } #endregion // 解密ticket -> 转为实体对象 TicketModel ticketModel = null; try { string ticketJsonStr = _encryptHelper.Decrypt(ticket, _options.EncryptKey); // TODO: fixed: 临时修复, 直接将全部为0的字节去除, byte[] bytes = Encoding.UTF8.GetBytes(ticketJsonStr); byte[] remove0Bytes = bytes.Where(m => m != 0).ToArray(); string remove0ByteStr = Encoding.UTF8.GetString(remove0Bytes); // 能够转换为 对象, 则说明 vCodeKey 无误, 可以使用 ticketModel = JsonHelper.Deserialize <TicketModel>(remove0ByteStr); //ticketModel = JsonHelper.Deserialize<TicketModel>(ticketJsonStr); } catch (Exception ex) { // TODO: AES加解密后多出0, 导致无法转为json对象, 和验证码效验时一样 // '0x00' is invalid after a single JSON value. Expected end of data. LineNumber: 0 | BytePositionInLine: 110. _logHelper?.Write(ex.Message); } if (ticketModel == null) { // ticket无效,被篡改 rtnResult = new TicketVerifyResponseModel { code = -4, message = "ticket无效" }; return(rtnResult); } // 从内存中取出此用户会话保存的独有Ticket,进行比对 string cacheKeyTicket = CachePrefixTicket + userId; if (!_cacheHelper.Exists(cacheKeyTicket)) { // ticket无效,1.此ticket已被效验过一次,用完销毁 2.其它原因: 伪造ticket rtnResult = new TicketVerifyResponseModel { code = -5, message = "ticket无效" }; return(rtnResult); } string rightTicket = _cacheHelper.Get(cacheKeyTicket).ToString(); if (ticket != rightTicket) { // ticket无效,1.篡改ticket rtnResult = new TicketVerifyResponseModel { code = -6, message = "ticket无效" }; RemoveCacheTicket(userId); return(rtnResult); } if (!ticketModel.IsPass) { // ticket 标识 验证不通过 rtnResult = new TicketVerifyResponseModel { code = -1, message = "验证不通过" }; RemoveCacheTicket(userId); return(rtnResult); } int secOffset = (int)((DateTimeHelper.NowTimeStamp13() - ticketModel.TS) / 1000); if (secOffset > _options.ExpiredSec) { // ticket 已过期 rtnResult = new TicketVerifyResponseModel { code = -2, message = "ticket过期" }; RemoveCacheTicket(userId); return(rtnResult); } if (ticketModel.IP != userIp) { // ip不匹配 rtnResult = new TicketVerifyResponseModel { code = -3, message = "ip不匹配" }; RemoveCacheTicket(userId); return(rtnResult); } // 验证通过 rtnResult = new TicketVerifyResponseModel { code = 0, message = "验证通过" }; RemoveCacheTicket(userId); return(rtnResult); }