/// <summary>
        /// 提取token,反推出用户信息
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
        {
            var auth_type  = context.Scheme.Name;
            var _context   = context.HttpContext;
            var _principal = context.Principal ?? new ClaimsPrincipal();

            try
            {
                var token = new string[] {
                    _context.Request.Headers["auth_token"],
                    _principal.FindFirst(ClaimTypes.NameIdentifier)?.Value
                }.FirstNotEmpty_();

                if (ValidateHelper.IsEmpty(token))
                {
                    throw new MsgException("token不存在");
                }

                //缓存相关
                var key_manager = _context.RequestServices.Resolve_ <ICacheKeyManager>();
                var _cache      = _context.RequestServices.ResolveDistributedCache_();

                //把登录数据缓存到http上下文
                var cache_key      = key_manager.AuthHttpItemKey(auth_type);
                var loginuser_json = await _context.CacheInHttpContextAsync(cache_key, async() =>
                {
                    var token_data = await this.FindTokenOrThrow(key_manager, _cache, _context, token);
                    var user_data  = await this.FindUserOrThrow(key_manager, _cache, _context, token_data.Data.UserUID);

                    return(user_data.Data.ToJson());
                });

                if (ValidateHelper.IsEmpty(loginuser_json))
                {
                    throw new MsgException(nameof(loginuser_json));
                }

                //生成identity
                var identities = _principal.Identities.Where(x => x.AuthenticationType != auth_type).ToList();

                var identity = new ClaimsIdentity(authenticationType: auth_type);
                identity.AddClaim_(ClaimTypes.UserData, loginuser_json);

                identities.Add(identity);
                var loginuser = new ClaimsPrincipal(identities: identities);

                context.ReplacePrincipal(loginuser);
            }
            catch (MsgException)
            {
                context.RejectPrincipal();
            }
            catch (Exception e)
            {
                context.HttpContext.RequestServices.ResolveLogger <MyCookieAuthenticationEvents>().AddErrorLog(e.Message, e);

                context.RejectPrincipal();
            }
            await base.ValidatePrincipal(context);
        }
        /// <summary>
        /// 抹掉大部分信息,只留token
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override async Task SigningIn(CookieSigningInContext context)
        {
            var _context = context.HttpContext;

            try
            {
                var auth_type = context.Scheme.Name;

                var json = context.Principal?.FindFirst(ClaimTypes.UserData)?.Value;
                if (ValidateHelper.IsEmpty(json))
                {
                    throw new ArgumentException("未找到用户数据");
                }

                var loginuser = json.JsonToEntity <WCloudUserInfo>() ?? throw new ArgumentException("数据格式错误");
                var token     = loginuser.ExtraData["token"];

                if (ValidateHelper.IsEmpty(token))
                {
                    throw new ArgumentException("token不存在");
                }

                var identity = new ClaimsIdentity(authenticationType: auth_type);
                identity.AddClaim_(ClaimTypes.NameIdentifier, token);
                context.Principal = new ClaimsPrincipal(identity);

                await base.SigningIn(context);

                //缓存相关
                var key_manager = _context.RequestServices.Resolve_ <ICacheKeyManager>();
                var _cache      = _context.RequestServices.ResolveDistributedCache_();

                //删除用户缓存
                var key = key_manager.UserInfo(loginuser.UserID);
                await _cache.RemoveAsync(key);

                //删除token缓存
                key = key_manager.AuthToken(token);
                await _cache.RemoveAsync(key);
            }
            catch (Exception e)
            {
                throw new LoginException("登录异常", e);
            }
        }