Abp 微信小程序登录 基本的流程和实践

需求:有个web端,然后移动端使用微信小程序。要把微信用户和系统中的用户对应起来

上一篇搞了个钉钉小程序登录:钉钉小程序登录

 

微信小程序登录,方便用户输入和系统中校验的也就只有手机号了,既能保证用户唯一标识,也能和系统中的用户关联起来。

数据库表:Abp 微信小程序登录 基本的流程和实践_第1张图片

AbpUserLogins 表是 AbpUsers表和第三方登录的中介

AbpUser表中的PhoneNumber就是这个Providerkey

首先

微信小程序->

     wx.login -> 获取到code -> 后端用code 去拿用户openid和session_key ->返回到前台,微信小程序使用getPhoneNumber-》获取到 iv,encryptedData,加上刚才的session_key -> 后端 解密到手机号,用手机号对应到系统中的用户,然后进行必要的校验-》返回token

作者地址:https://blog.csdn.net/qq_36279445



        /// 
        /// 微信小程序登录 拿code换 session_key, openid
        /// 
        /// 
        /// 
        [HttpGet]
        public async Task GetWeChatToken(ExternalGetTokenModel model)
        {
            return await _wechatMiniProgramAuthProviderApi.GetWeChatToken(model);
        }

        /// 
        /// 点击获取手机号 -》 session_key,iv, encryptedData
        /// 
        /// 
        /// 
        [HttpPost]
        public async Task WechatAuthenticate([FromBody] ExternalWechatAuthenticateModel model)
        {
            _currentTenant = _tenantManager.GetTenantByDomainName(model.DomainName);

            // 给全局的租户赋值,不然没法访问数据库
            _unitOfWorkManager.Current.SetTenantId(_currentTenant.Id);

            //string phoneNumber = getPhoneNumber(model);
            string phoneNumber = "18253132526";
            var user = await _userManager.GetUserByPhoneNumberAsync(phoneNumber);
            if (user == null)
            {
                throw new UserFriendlyException($"手机号为{phoneNumber}的微信用户在系统内不存在!");
            }

            model.AuthProvider = ProviderName;
            model.ProviderKey = phoneNumber;
            //model.ProviderKey = user.PhoneNumber;

            var loginResult = await _logInManager.LoginAsync(new UserLoginInfo(model.AuthProvider, model.ProviderKey, model.AuthProvider), _currentTenant.TenancyName);

            switch (loginResult.Result)
            {
                case AbpLoginResultType.Success:
                    {
                        var accessToken = CreateAccessToken(CreateJwtClaims(loginResult.Identity));
                        return new AuthenticateResultModel
                        {
                            AccessToken = accessToken,
                            EncryptedAccessToken = GetEncryptedAccessToken(accessToken),
                            ExpireInSeconds = (int)_configuration.Expiration.TotalSeconds,
                            UserId = loginResult.User.Id
                        };
                    }
                case AbpLoginResultType.UnknownExternalLogin:
                    {
                        // 理论上不会走这里了
                        // Try to login again with newly registered user!
                        loginResult = await _logInManager.LoginAsync(new UserLoginInfo(model.AuthProvider, model.ProviderKey, model.AuthProvider), _currentTenant.TenancyName);
                        var accessToken = CreateAccessToken(CreateJwtClaims(loginResult.Identity));
                        if (loginResult.Result != AbpLoginResultType.Success)
                        {
                            throw _abpLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt(
                                loginResult.Result,
                                model.ProviderKey,
                                _currentTenant.TenancyName
                            );
                        }

                        return new AuthenticateResultModel
                        {
                            AccessToken = accessToken,
                            EncryptedAccessToken = GetEncryptedAccessToken(accessToken),
                            ExpireInSeconds = (int)_configuration.Expiration.TotalSeconds,
                            UserId = loginResult.User.Id
                        };
                    }
                default:
                    {
                        throw _abpLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt(
                            loginResult.Result,
                            model.ProviderKey,
                            _currentTenant.TenancyName
                        );
                    }
            }
        }

        /// 
        /// 获取用户手机号,session_key, iv, encryptedData
        /// 
        /// 
        private string getPhoneNumber(ExternalWechatAuthenticateModel externalWechatAuthenticateModel)
        {
            try
            {
                byte[] encryData = Convert.FromBase64String(externalWechatAuthenticateModel.encryptedData);
                RijndaelManaged rijndaelCipher = new RijndaelManaged();
                rijndaelCipher.Key = Convert.FromBase64String(externalWechatAuthenticateModel.session_key);
                rijndaelCipher.IV = Convert.FromBase64String(externalWechatAuthenticateModel.iv);
                rijndaelCipher.Mode = CipherMode.CBC;
                rijndaelCipher.Padding = PaddingMode.PKCS7;
                ICryptoTransform transform = rijndaelCipher.CreateDecryptor();
                byte[] plainText = transform.TransformFinalBlock(encryData, 0, encryData.Length);
                string result = Encoding.Default.GetString(plainText);

                dynamic model = Newtonsoft.Json.Linq.JToken.Parse(result) as dynamic;
                string phoneNumber = model.phoneNumber;
                //return model.phoneNumber;
                if (string.IsNullOrEmpty(phoneNumber))
                {
                    return "";
                }
                return phoneNumber;
            }
            catch (Exception ex)
            {
                throw new UserFriendlyException($"获取用户手机号报错:{ex.Message}");
            }
        }

 

 

你可能感兴趣的:(.Net,C#)