protected virtual async Task <LoginResultInfoModel> GetLoginResultAsync(LoginInput input)
        {
            var tenantId      = CurrentTenant.Id;
            var tenantChanged = false;

            MiniProgram miniProgram;

            if (input.LookupUseRecentlyTenant)
            {
                using (_dataFilter.Disable <IMultiTenant>())
                {
                    miniProgram = await _miniProgramRepository.FirstOrDefaultAsync(x => x.AppId == input.AppId);
                }
            }
            else
            {
                miniProgram = await _miniProgramRepository.GetAsync(x => x.AppId == input.AppId);
            }

            var code2SessionResponse =
                await _loginService.Code2SessionAsync(miniProgram.AppId, miniProgram.AppSecret, input.Code);

            var openId  = code2SessionResponse.OpenId;
            var unionId = code2SessionResponse.UnionId;

            if (input.LookupUseRecentlyTenant)
            {
                using (_dataFilter.Disable <IMultiTenant>())
                {
                    tenantId = await _miniProgramUserRepository.FindRecentlyTenantIdAsync(input.AppId, openId, true);
                }

                if (tenantId != CurrentTenant.Id)
                {
                    tenantChanged = true;
                }
            }

            using var tenantChange = CurrentTenant.Change(tenantId);

            if (tenantChanged)
            {
                miniProgram = await _miniProgramRepository.GetAsync(x => x.AppId == input.AppId);
            }

            string loginProvider;
            string providerKey;

            if (!unionId.IsNullOrWhiteSpace())
            {
                loginProvider = await _miniProgramLoginProviderProvider.GetOpenLoginProviderAsync(miniProgram);

                providerKey = unionId;
            }
            else
            {
                loginProvider = await _miniProgramLoginProviderProvider.GetAppLoginProviderAsync(miniProgram);

                providerKey = openId;
            }
            return(new LoginResultInfoModel
            {
                MiniProgram = miniProgram,
                LoginProvider = loginProvider,
                ProviderKey = providerKey,
                UnionId = unionId,
                Code2SessionResponse = code2SessionResponse
            });
        }
示例#2
0
        protected virtual async Task <LoginResultInfoModel> GetLoginResultAsync(LoginInput input)
        {
            var tenantId      = CurrentTenant.Id;
            var tenantChanged = false;

            MiniProgram miniProgram;

            if (input.LookupUseRecentlyTenant)
            {
                using (_dataFilter.Disable <IMultiTenant>())
                {
                    miniProgram = await _miniProgramRepository.FirstOrDefaultAsync(x => x.AppId == input.AppId);
                }
            }
            else
            {
                miniProgram = await _miniProgramRepository.GetAsync(x => x.AppId == input.AppId);
            }

            var code2SessionResponse =
                await _loginService.Code2SessionAsync(miniProgram.AppId, miniProgram.AppSecret, input.Code);

            _signatureChecker.Check(input.RawData, code2SessionResponse.SessionKey, input.Signature);

            var openId  = code2SessionResponse.OpenId;
            var unionId = code2SessionResponse.UnionId;

            if (input.LookupUseRecentlyTenant)
            {
                using (_dataFilter.Disable <IMultiTenant>())
                {
                    tenantId = await _miniProgramUserRepository.FindRecentlyTenantIdAsync(input.AppId, openId, true);
                }

                if (tenantId != CurrentTenant.Id)
                {
                    tenantChanged = true;
                }
            }

            using var tenantChange = CurrentTenant.Change(tenantId);

            if (tenantChanged)
            {
                miniProgram = await _miniProgramRepository.GetAsync(x => x.AppId == input.AppId);
            }

            // 如果 auth.code2Session 没有返回用户的 UnionId
            if (unionId.IsNullOrWhiteSpace())
            {
                if (!input.EncryptedData.IsNullOrWhiteSpace() && !input.Iv.IsNullOrWhiteSpace())
                {
                    // 方法1:通过 EncryptedData 和 Iv 解密获得用户的 UnionId
                    var decryptedData =
                        _jsonSerializer.Deserialize <Dictionary <string, object> >(
                            AesHelper.AesDecrypt(input.EncryptedData, input.Iv, code2SessionResponse.SessionKey));

                    unionId = decryptedData.GetOrDefault("unionId") as string;
                }
                else
                {
                    // 方法2:尝试通过 OpenId 在 MiniProgramUser 实体中查找用户的 UnionId
                    // Todo: should use IMiniProgramUserStore
                    unionId = await _miniProgramUserRepository.FindUnionIdByOpenIdAsync(miniProgram.Id, openId);
                }
            }

            string loginProvider;
            string providerKey;

            if (unionId.IsNullOrWhiteSpace())
            {
                loginProvider = await _miniProgramLoginProviderProvider.GetAppLoginProviderAsync(miniProgram);

                providerKey = openId;
            }
            else
            {
                loginProvider = await _miniProgramLoginProviderProvider.GetOpenLoginProviderAsync(miniProgram);

                providerKey = unionId;
            }
            return(new LoginResultInfoModel
            {
                MiniProgram = miniProgram,
                LoginProvider = loginProvider,
                ProviderKey = providerKey,
                UnionId = unionId,
                Code2SessionResponse = code2SessionResponse
            });
        }
        public virtual async Task <string> LoginAsync(LoginInput input)
        {
            var miniProgram = await _miniProgramRepository.GetAsync(x => x.AppId == input.AppId);

            var code2SessionResponse =
                await _loginService.Code2SessionAsync(miniProgram.AppId, miniProgram.AppSecret, input.Code);

            _signatureChecker.Check(input.RawData, code2SessionResponse.SessionKey, input.Signature);

            var openId  = code2SessionResponse.OpenId;
            var unionId = code2SessionResponse.UnionId;

            if (input.LookupUseRecentlyTenant)
            {
                Guid?tenantId;

                using (_dataFilter.Disable <IMultiTenant>())
                {
                    tenantId = await _miniProgramUserRepository.FindRecentlyTenantIdAsync(miniProgram.Id, openId);
                }

                using var tenantChange = CurrentTenant.Change(tenantId);
            }

            string loginProvider;
            string providerKey;

            // 如果 auth.code2Session 没有返回用户的 UnionId
            if (unionId.IsNullOrWhiteSpace())
            {
                if (!input.EncryptedData.IsNullOrWhiteSpace() && !input.Iv.IsNullOrWhiteSpace())
                {
                    // 方法1:通过 EncryptedData 和 Iv 解密获得用户的 UnionId
                    var decryptedData =
                        _jsonSerializer.Deserialize <Dictionary <string, object> >(
                            AesHelper.AesDecrypt(input.EncryptedData, input.Iv, code2SessionResponse.SessionKey));

                    unionId = decryptedData.GetOrDefault("unionId") as string;
                }
                else
                {
                    // 方法2:尝试通过 OpenId 在 MiniProgramUser 实体中查找用户的 UnionId
                    // Todo: should use IMiniProgramUserStore
                    unionId = await _miniProgramUserRepository.FindUnionIdByOpenIdAsync(miniProgram.Id, openId);
                }
            }

            if (unionId.IsNullOrWhiteSpace())
            {
                loginProvider = await _miniProgramLoginProviderProvider.GetAppLoginProviderAsync(miniProgram);

                providerKey = openId;
            }
            else
            {
                loginProvider = await _miniProgramLoginProviderProvider.GetOpenLoginProviderAsync(miniProgram);

                providerKey = unionId;
            }

            var identityUser = await _identityUserManager.FindByLoginAsync(loginProvider, providerKey) ??
                               await _miniProgramLoginNewUserCreator.CreateAsync(input.UserInfo, loginProvider, providerKey);

            await UpdateMiniProgramUserAsync(identityUser, miniProgram, unionId, openId, code2SessionResponse.SessionKey);
            await UpdateUserInfoAsync(identityUser, input.UserInfo);

            return((await RequestIds4LoginAsync(input.AppId, unionId, openId))?.Raw);
        }