/// <summary>绑定用户,用户未有效绑定或需要强制绑定时</summary> /// <param name="uc"></param> /// <param name="client"></param> public virtual IManageUser OnBind(UserConnect uc, OAuthClient client) { var prv = Provider; var mode = ""; // 如果未登录,需要注册一个 var user = prv.Current; if (user == null) { var set = Setting.Current; if (!set.AutoRegister) { throw new InvalidOperationException("绑定要求本地已登录!"); } // 先找用户名,如果存在,就加上提供者前缀,直接覆盖 var name = client.UserName; if (name.IsNullOrEmpty()) { name = client.NickName; } if (!name.IsNullOrEmpty()) { // 强制绑定本地用户时,没有前缀 if (set.ForceBindUser) { mode = "UserName"; user = prv.FindByName(name); } else { mode = "Provider-UserName"; name = client.Name + "_" + name; user = prv.FindByName(name); } } // 匹配Code if (user == null && set.ForceBindUserCode) { mode = "UserCode"; if (!client.UserCode.IsNullOrEmpty()) { user = UserX.FindByCode(client.UserCode); } } // 匹配Mobile if (user == null && set.ForceBindUserMobile) { mode = "UserMobile"; if (!client.Mobile.IsNullOrEmpty()) { user = UserX.FindByMobile(client.Mobile); } } // 匹配Mail if (user == null && set.ForceBindUserMail) { mode = "UserMail"; if (!client.Mail.IsNullOrEmpty()) { user = UserX.FindByMail(client.Mail); } } // QQ、微信 等不返回用户名 if (user == null && name.IsNullOrEmpty()) { // OpenID和AccessToken不可能同时为空 var openid = client.OpenID; if (openid.IsNullOrEmpty()) { openid = client.AccessToken; } // 过长,需要随机一个较短的 var num = openid.GetBytes().Crc(); mode = "OpenID-Crc"; name = client.Name + "_" + num.ToString("X8"); user = prv.FindByName(name); } if (user == null) { mode = "Register"; // 新注册用户采用魔方默认角色 var rid = Role.GetOrAdd(set.DefaultRole).ID; //if (rid == 0 && client.Items.TryGetValue("roleid", out var roleid)) rid = roleid.ToInt(); //if (rid <= 0) rid = GetRole(client.Items, rid < -1); // 注册用户,随机密码 user = prv.Register(name, Rand.NextString(16), rid, true); //if (user is UserX user2) user2.RoleIDs = GetRoles(client.Items, rid < -2).Join(); } } uc.UserID = user.ID; uc.Enable = true; // 写日志 var log = LogProvider.Provider; log?.WriteLog(typeof(UserX), "绑定", true, $"[{user}]依据[{mode}]绑定到[{client.Name}]的[{client.UserName}]", user.ID, user + ""); return(user); }
/// <summary>登录</summary> /// <param name="name"></param> /// <param name="password"></param> /// <param name="remember">是否记住密码</param> /// <returns></returns> public override IManageUser Login(String name, String password, Boolean remember) { //var user = UserX.Login(name, password, rememberme); UserX user; try { // 用户登录,依次支持用户名、邮箱、手机、编码 var account = name.Trim(); user = UserX.FindByName(account); if (user == null && account.Contains("@")) { user = UserX.FindByMail(account); } if (user == null && account.ToLong() > 0) { user = UserX.FindByMobile(account); } if (user == null) { user = UserX.FindByCode(account); } if (user == null) { throw new EntityException("帐号{0}不存在!", account); } if (!user.Enable) { throw new EntityException("账号{0}被禁用!", account); } // 数据库为空密码,任何密码均可登录 if (!user.Password.IsNullOrEmpty()) { var ss = password.Split(':'); if (ss.Length <= 1) { if (!password.MD5().EqualIgnoreCase(user.Password)) { throw new EntityException("密码不正确!"); } } else { var salt = ss[1]; var pass = (user.Password.ToLower() + salt).MD5(); if (!ss[0].EqualIgnoreCase(pass)) { throw new EntityException("密码不正确!"); } } } // 保存登录信息 user.Logins++; user.LastLogin = DateTime.Now; user.LastLoginIP = UserHost; user.Update(); UserX.WriteLog("登录", true, $"用户[{user}]使用[{name}]登录成功"); } catch (Exception ex) { UserX.WriteLog("登录", false, name + "登录失败!" + ex.Message); throw; } Current = user; // 过期时间 var set = Setting.Current; var expire = TimeSpan.FromMinutes(0); if (remember && user != null) { expire = TimeSpan.FromDays(365); } else { if (set.SessionTimeout > 0) { expire = TimeSpan.FromSeconds(set.SessionTimeout); } } // 保存Cookie var context = Context?.HttpContext; this.SaveCookie(user, expire, context); return(user); }