public virtual async Task BindAsync(LoginInput input) { await CheckBindPolicyAsync(); var miniProgram = await _miniProgramRepository.GetAsync(x => x.AppId == input.AppId); var loginResult = await GetLoginResultAsync(miniProgram, input); await _identityOptions.SetAsync(); if (await _identityUserManager.FindByLoginAsync(loginResult.LoginProvider, loginResult.ProviderKey) != null) { throw new WechatAccountHasBeenBoundException(); } var identityUser = await _identityUserManager.GetByIdAsync(CurrentUser.GetId()); (await _identityUserManager.AddLoginAsync(identityUser, new UserLoginInfo(loginResult.LoginProvider, loginResult.ProviderKey, WeChatManagementCommonConsts.WeChatUserLoginInfoDisplayName))).CheckErrors(); await UpdateMiniProgramUserAsync(identityUser, miniProgram, loginResult.Code2SessionResponse.UnionId, loginResult.Code2SessionResponse.OpenId, loginResult.Code2SessionResponse.SessionKey); await UpdateUserInfoAsync(identityUser, input.UserInfo); }
/// <summary> /// 通过微信开放能力获取并给当前用户绑定手机号,更新信息:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html /// </summary> /// <param name="input"></param> /// <returns></returns> /// <exception cref="BusinessException"></exception> /// <exception cref="AbpIdentityResultException"></exception> public async Task BindPhoneNumberAsync(BindPhoneNumberInput input) { await _identityOptions.SetAsync(); var user = await _identityUserManager.GetByIdAsync(CurrentUser.GetId()); var miniProgram = await _miniProgramRepository.GetAsync(x => x.AppId == input.AppId); var response = await _loginService.Code2SessionAsync(miniProgram.AppId, miniProgram.AppSecret, input.Code); if (response.ErrorCode != 0) { throw new BusinessException(message: $"WeChat error: [{response.ErrorCode}]: {response.ErrorMessage}"); } var decryptedData = _jsonSerializer.Deserialize <Dictionary <string, object> >(AesHelper .AesDecrypt(input.EncryptedData, input.Iv, response.SessionKey)); var phoneNumber = decryptedData["phoneNumber"] as string; _identityUserManager.RegisterTokenProvider(TokenOptions.DefaultPhoneProvider, new StaticPhoneNumberTokenProvider()); var token = await _identityUserManager.GenerateChangePhoneNumberTokenAsync(user, phoneNumber); var identityResult = await _identityUserManager.ChangePhoneNumberAsync(user, phoneNumber, token); if (!identityResult.Succeeded) { throw new AbpIdentityResultException(identityResult); } }
public virtual async Task ValidateAsync(ExtensionGrantValidationContext context) { await _identityOptions.SetAsync(); var appId = context.Request.Raw.Get("appid"); var openId = context.Request.Raw.Get("openid"); var unionId = context.Request.Raw.Get("unionid"); if (string.IsNullOrWhiteSpace(appId)) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant) { ErrorDescription = "请提供有效的 appid" }; return; } if (string.IsNullOrWhiteSpace(openId)) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant) { ErrorDescription = "微信服务器没有提供有效的 openid" }; return; } var miniProgram = await _miniProgramRepository.GetAsync(x => x.AppId == appId); string loginProvider; string providerKey; 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); var claims = new List <Claim> { // 记录 appid new Claim("appid", appId) }; claims.AddRange(identityUser.Claims.Select(item => new Claim(item.ClaimType, item.ClaimValue))); context.Result = new GrantValidationResult(identityUser.Id.ToString(), GrantType, claims); }
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 }); }
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 }); }
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); }