/// <summary>
        /// 保存token
        /// </summary>
        /// <param name="context"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        private async Task SaveToken(HttpContext context, RequestDelegate next)
        {
            string responseContent;

            var originalBodyStream = context.Response.Body;

            using (var fakeResponseBody = new MemoryStream())
            {
                context.Response.Body = fakeResponseBody;

                await next(context);

                fakeResponseBody.Seek(0, SeekOrigin.Begin);
                using (var reader = new StreamReader(fakeResponseBody))
                {
                    responseContent = await reader.ReadToEndAsync();

                    fakeResponseBody.Seek(0, SeekOrigin.Begin);

                    await fakeResponseBody.CopyToAsync(originalBodyStream);
                }
            }

            if (StatusCodeChecker.Is2xx(context.Response.StatusCode))
            {
                var tokenTxt = JObject.Parse(responseContent).GetValue("token")?.ToString();
                if (tokenTxt.IsNullOrWhiteSpace())
                {
                    return;
                }
                //refreshTokenTxt = JObject.Parse(responseContent).GetValue("refreshToken").ToString();

                var claimsInfo = GetClaimsInfo(tokenTxt);
                if (claimsInfo.Account.IsNotNullOrWhiteSpace())
                {
                    var tokenKey = $"{tokenPrefx}:{claimsInfo.Account}:{claimsInfo.Id}";
                    _cache.Set(tokenKey, claimsInfo.Token, claimsInfo.Expire - DateTime.Now);
                    //var refreshTokenKey = $"{refreshTokenPrefx}:{claimsInfo.Account}:{claimsInfo.Id}";
                    //_cache.Set(refreshTokenKey, refreshTokenTxt, TimeSpan.FromSeconds(_jwtConfig.RefreshTokenExpire));
                }
            }
        }
        public async Task Invoke(HttpContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var endpoint = context.GetEndpoint();

            if (endpoint == null)
            {
                await _next(context);

                return;
            }

            var requiredValues = ((RouteEndpoint)endpoint).RoutePattern.RequiredValues;

            if (!requiredValues.Any())
            {
                await _next(context);

                return;
            }

            var controller = requiredValues["controller"]?.ToString().ToLower();
            var action     = requiredValues["action"]?.ToString().ToLower();

            if (controller.IsNullOrWhiteSpace())
            {
                await _next(context);

                return;
            }

            //判断Api是否需要认证
            bool isNeedAuthentication = endpoint.Metadata.GetMetadata <IAllowAnonymous>() == null;

            //Api不需要认证
            if (!isNeedAuthentication)
            {
                //如果是调用登录API、刷新token的Api,并且调用成功,需要保存accesstoken到cache
                if (controller == "account" && (action == "login" || action == "refreshaccesstoken"))
                {
                    await SaveToken(context, _next);

                    return;
                }

                //其他Api
                await _next(context);

                return;
            }

            //API需要认证
            if (isNeedAuthentication)
            {
                //是修改密码,需要从cahce移除Token
                if (controller == "account" && action == "password")
                {
                    await _next(context);

                    if (StatusCodeChecker.Is2xx(context.Response.StatusCode))
                    {
                        await RemoveToken(context);
                    }
                    return;
                }

                //是注销,需要判断是否主动注销
                if (controller == "account" && action == "logout")
                {
                    await _next(context);

                    if (StatusCodeChecker.Is2xx(context.Response.StatusCode))
                    {
                        //主动注销,从cahce移除token
                        if (await CheckToken(context))
                        {
                            await RemoveToken(context);
                        }
                        return;
                    }
                }
            }

            //API需要认证,并且验证成功,需要检查accesstoken是否在缓存中。
            if (StatusCodeChecker.Is2xx(context.Response.StatusCode))
            {
                //需要先检查token是否是最新的,再走其它中间件
                var result = await CheckToken(context);

                if (result)
                {
                    try
                    {
                        await _next(context);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(ex.Message, ex);
                    }
                    return;
                }
                else
                {
                    var status         = (int)HttpStatusCode.Unauthorized;
                    var hostAndPort    = context.Request.Host.HasValue ? context.Request.Host.Value : string.Empty;
                    var requestUrl     = string.Concat(hostAndPort, context.Request.Path);
                    var type           = string.Concat("https://httpstatuses.com/", status);
                    var title          = "Token已经过期";
                    var detial         = "Token已经过期,请重新登录";
                    var problemDetails = new ProblemDetails
                    {
                        Title = title
                        ,
                        Detail = detial
                        ,
                        Type = type
                        ,
                        Status = status
                        ,
                        Instance = requestUrl
                    };
                    context.Response.StatusCode  = status;
                    context.Response.ContentType = "application/problem+json";
                    var stream = context.Response.Body;
                    await JsonSerializer.SerializeAsync(stream, problemDetails);

                    return;
                }
            }

            await _next(context);
        }
        public async Task Invoke(HttpContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var endpoint = context.GetEndpoint();

            if (endpoint == null)
            {
                await _next(context);

                return;
            }

            var requiredValues = ((RouteEndpoint)endpoint).RoutePattern.RequiredValues;

            if (requiredValues.Count() == 0)
            {
                await _next(context);

                return;
            }

            var controller = requiredValues["controller"]?.ToString().ToLower();
            var action     = requiredValues["action"]?.ToString().ToLower();

            if (controller.IsNullOrWhiteSpace())
            {
                await _next(context);

                return;
            }

            //判断Api是否需要认证
            bool isNeedAuthentication = endpoint.Metadata.GetMetadata <IAllowAnonymous>() == null ? true : false;

            //Api不需要认证
            if (isNeedAuthentication == false)
            {
                //如果是调用登录API、刷新token的Api,并且调用成功,需要保存accesstoken到cache
                if (controller == "account" && (action == "login" || action == "refreshaccesstoken"))
                {
                    await SaveToken(context, _next);

                    return;
                }

                //其他Api
                await _next(context);

                return;
            }

            //API需要认证
            if (isNeedAuthentication == true)
            {
                //是修改密码,需要从cahce移除Token
                if (controller == "account" && action == "password")
                {
                    await _next(context);

                    if (StatusCodeChecker.Is2xx(context.Response.StatusCode))
                    {
                        await RemoveToken(context);
                    }
                    return;
                }

                //是注销,需要判断是否主动注销
                if (controller == "account" && action == "logout")
                {
                    await _next(context);

                    if (StatusCodeChecker.Is2xx(context.Response.StatusCode))
                    {
                        //主动注销,从cahce移除token
                        if (await CheckToken(context) == true)
                        {
                            await RemoveToken(context);
                        }
                        return;
                    }
                }
            }

            //API需要认证,并且验证成功,需要检查accesstoken是否在缓存中。
            if (StatusCodeChecker.Is2xx(context.Response.StatusCode))
            {
                //需要先检查token是否是最新的,再走其它中间件
                var result = await CheckToken(context);

                if (result)
                {
                    await _next(context);

                    return;
                }
                else
                {
                    context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                    var message = new ErrorModel(HttpStatusCode.Unauthorized, "账号已经在其他地方登录");
                    context.Response.ContentType = "application/json;charset=utf-8";
                    await context.Response.WriteAsync(message.ToString());

                    return;
                }
            }

            await _next(context);

            return;
        }