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); }