diff --git a/New_College.Api/Controllers/Front/CustomerController.cs b/New_College.Api/Controllers/Front/CustomerController.cs index c0fbe26..fafa06d 100644 --- a/New_College.Api/Controllers/Front/CustomerController.cs +++ b/New_College.Api/Controllers/Front/CustomerController.cs @@ -95,7 +95,7 @@ namespace New_College.Api.Controllers.Front var single = singlelist.FirstOrDefault(); if (single != null) { - updatesync(single.Phone); + // updatesync(single.Phone); //var custome = new CustomerUpdateQuery() //{ // StudentId = single.Id, @@ -179,14 +179,18 @@ namespace New_College.Api.Controllers.Front var result = _services.AuthCode2Session(login.code); if (result.openid != "" && result.openid != null) { - var loginstatus = _services.Logined(new LoginQuery() { openId = result.openid }).Result; + var loginstatus = _services.Logined(new LoginQuery() { openId = result.openid, unionId = result.unionid }).Result; if (loginstatus.Item1) { response = loginstatus.Item2; } else { - var save = _services.CustomerSave(new DecryptUserInfoRequest() { openid = result.openid }).Result; + var save = _services.CustomerSave(new DecryptUserInfoRequest() + { + openid = result.openid, + UnionId = result.unionid + }).Result; response.OpenId = result.openid; response.Id = save; } diff --git a/New_College.Api/Controllers/OAuthController.cs b/New_College.Api/Controllers/OAuthController.cs index 5b93009..bd9a5e2 100644 --- a/New_College.Api/Controllers/OAuthController.cs +++ b/New_College.Api/Controllers/OAuthController.cs @@ -29,48 +29,6 @@ namespace New_College.Controllers _CustomerInfoServices = v_CustomerInfoServices; } - - - /// - ///三方登录 - /// - /// - /// - //[Route("login")] - //public async Task> Login([FromQuery] ThridLoginRequestDto dto) - //{ - // string token = string.Empty; - // if (dto == null) - // { - // return new MessageModel() - // { - // success = false, - // msg = "参数错误", - - // }; - // } - // if (ThridConfig.secretKey != dto.secretKey) - // { - // return new MessageModel() - // { - // success = false, - // msg = "密钥错误", - // }; - // } - // //首先判断是否存在账户| - // //不存在则创建新的账户| - // //存在则直接登录| - - - - // return new MessageModel() - // { - // msg = "ok", - // success = true, - // response = token - // }; - //} - /// /// Oauth2验证回调 /// @@ -85,92 +43,52 @@ namespace New_College.Controllers var response = new CasDoorToken(); string jwtStr = string.Empty; bool suc = false; - var getaccesstoken = CasdoorHttpHelper.Http_Post("api/login/oauth/access_token", null, new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(new CasdoorRequest() { code = code, grant_type = "authorization_code", client_id = CasdoorConfig.ClientId, client_secret = CasdoorConfig.ClientSecret }), Encoding.UTF8, "application/json"));//获取access_token - var headers = new System.Collections.Generic.Dictionary - { - { "Authorization", string.Format("Bearer {0}", getaccesstoken.access_token) } - }; - if (getaccesstoken.access_token == null) - { - return new MessageModel() - { - msg = "code已失效", - success = false, - status = 401, - }; - } - response.servicetoken = getaccesstoken.access_token; - var userinfo = CasdoorHttpHelper.Http_Get("/api/userinfo", headers, new Dictionary()); - var user = (await _CustomerInfoServices.Query(q => q.UUID == userinfo.sub)).FirstOrDefault(); - if (user == null) - { - if (!string.IsNullOrWhiteSpace(userinfo.phone)) - { - var baseuser = (await _CustomerInfoServices.Query(q => q.Phone == userinfo.phone)).FirstOrDefault(); - - if (baseuser != null) + var userinfo = CasdoorHttpHelper.Http_Post>("/api/syswechat/user_info", null, + new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject( + new CasdoorRequest() { - if (string.IsNullOrEmpty(baseuser.NickName)) - { - - if (!string.IsNullOrWhiteSpace(baseuser.Phone)) - { - baseuser.NickName = baseuser.Phone; - } - } - baseuser.UUID = userinfo.sub; - user = baseuser; - await _CustomerInfoServices.Update(baseuser); - } - else + code = code, + client_id = CasdoorConfig.ClientId, + client_secret = CasdoorConfig.ClientSecret + }), + Encoding.UTF8, "application/json"));// + if (userinfo.code == 200 && userinfo.type == "success") + { + var user = (await _CustomerInfoServices.Query(q => q.UUID == userinfo.result.UnionId)).FirstOrDefault(); + if (user != null) + { + //没有用户则注册一个新用户 + user = new Model.Models.V_CustomerInfo() { - //没有用户则注册一个新用户 - - user = new Model.Models.V_CustomerInfo() - { - IsDelete = false, - UUID = userinfo.sub, - Phone = userinfo.phone, - OpenId = userinfo.aud, - CreateTime = DateTime.UtcNow, - IsVIP = false, - Gender = 0, - Subject = 1 - }; - user.Id = await _CustomerInfoServices.Add(user); - - } + IsDelete = false, + UUID = userinfo.result.UnionId, + Phone = userinfo.result.Mobile, + GZOpenId = userinfo.result.OpenId, + CreateTime = DateTime.UtcNow, + IsVIP = false, + Gender = 0, + Subject = 1, + NickName = userinfo.result.NickName, + ModifyTime = DateTime.UtcNow, + TenantId = userinfo.result.TenantId, + AvatarUrl = userinfo.result.Avatar, + CustomerType = CustomerTypeEnum.General + }; + user.Id = await _CustomerInfoServices.Add(user); } else { - return new MessageModel() - { - success = false, - msg = "该账户不存在或已注销" - }; + user.GZOpenId = userinfo.result.OpenId; + user.ModifyTime = DateTime.UtcNow; + await _CustomerInfoServices.Update(user); } + var tokenModel = new SSOTokenModelJwt { UserId = user.Id.ToString(), NickName = user.NickName, LoginMode = LoginModeEnum.APP.ToString() }; + jwtStr = JwtHelper.ssoIssueJwt(tokenModel); + response.token = jwtStr; + response.Id = user.Id; + suc = true; } - else - { - if (string.IsNullOrEmpty(user.NickName)) - { - var single = await _CustomerInfoServices.QueryById(user.Id); - if (!string.IsNullOrWhiteSpace(user.Phone)) - { - single.NickName = user.Phone; - } - if (!string.IsNullOrWhiteSpace(user.UserCode)) - { - single.NickName = user.UserCode; - } - await _CustomerInfoServices.Update(single); - } - } - TokenModelJwt tokenModel = new TokenModelJwt { Uid = user.Id, Role = "users" }; - jwtStr = JwtHelper.IssueJwt(tokenModel); - response.token = jwtStr; - response.Id = user.Id; - suc = true; + return new MessageModel() { success = suc, diff --git a/New_College.Api/New_College.Model.xml b/New_College.Api/New_College.Model.xml index 205f9f5..1e5ace9 100644 --- a/New_College.Api/New_College.Model.xml +++ b/New_College.Api/New_College.Model.xml @@ -3147,6 +3147,11 @@ 小程序openid + + + 公众号openid + + 用户名 @@ -3249,7 +3254,7 @@ - CasdoorId + UnionId @@ -3529,6 +3534,36 @@ 找不到指定资源 + + + 微信公众号 + + + + + 微信小程序 + + + + + QQ + + + + + 支付宝 + + + + + PC模式 + + + + + APP + + 异步添加种子数据 @@ -5760,6 +5795,71 @@ 选项标签 + + + 系统用户Id + + + + + 平台类型 + + + + + OpenId + + + + + UnionId + + + + + 昵称 + + + + + 头像 + + + + + 手机号码 + + + + + 性别 + + + + + 语言 + + + + + 城市 + + + + + 省 + + + + + 国家 + + + + + 租户Id + + 测试次数 diff --git a/New_College.Api/appsettings.Development.json b/New_College.Api/appsettings.Development.json index df8f7ef..77d1b25 100644 --- a/New_College.Api/appsettings.Development.json +++ b/New_College.Api/appsettings.Development.json @@ -116,10 +116,10 @@ } ], "Audience": { - "Secret": "sdfsdfsrty25634kkhllghtdgdfss345t678fs", //不要太短,16位+ + "Secret": "9c1cbc3f546eda35168c3aa3cb91780fbe703f0996c6d123ea96dc85c70bbc0a", //不要太短,16位+ "SecretFile": "", //安全。内容就是Secret - "Issuer": "New_College", - "Audience": "wr" + "Issuer": "YCYMEDUCENTER", + "Audience": "YCYMEDUCENTER" }, "Startup": { "Cors": { @@ -215,12 +215,12 @@ "endpoint": "https://oss-cn-shanghai.aliyuncs.com" }, "Casdoor": { - "Endpoint": "http://192.168.104.107:8000", + "Endpoint": "https://api.sso.ycymedu.com", "OrganizationName": "六纬生涯", "ApplicationName": "六纬生涯", "ApplicationType": "webapi", - "ClientId": "776d639918192c449537", - "ClientSecret": "d556f0692052a2df56614282dd86895b04783262", + "ClientId": "18592781518917", + "ClientSecret": "9c1cbc3f546eda35168c3aa3cb91780fbe703f0996c6d123ea96dc85c70bbc0a", "CallbackPath": "http://test.sso.ycymedu.com/login/oauth/authorize?client_id=776d639918192c449537&response_type=code&redirect_uri=http://192.168.100.106:8080/Home/FirstPage&scope=read&state=casdoor", "RequireHttpsMetadata": false }, diff --git a/New_College.Extensions/Authorizations/OverWrite/JwtHelper.cs b/New_College.Extensions/Authorizations/OverWrite/JwtHelper.cs index 35f1544..6bfd5c6 100644 --- a/New_College.Extensions/Authorizations/OverWrite/JwtHelper.cs +++ b/New_College.Extensions/Authorizations/OverWrite/JwtHelper.cs @@ -94,6 +94,61 @@ namespace New_College.AuthHelper.OverWrite }; return tm; } + + + public static string ssoIssueJwt(SSOTokenModelJwt tokenModel) + { + string iss = Appsettings.app(new string[] { "Audience", "Issuer" }); + string aud = Appsettings.app(new string[] { "Audience", "Audience" }); + string secret = AppSecretConfig.Audience_Secret_String; + + //var claims = new Claim[] //old + var claims = new List + { + /* + * 特别重要: + 1、这里将用户的部分信息,比如 uid 存到了Claim 中,如果你想知道如何在其他地方将这个 uid从 Token 中取出来,请看下边的SerializeJwt() 方法,或者在整个解决方案,搜索这个方法,看哪里使用了! + 2、你也可以研究下 HttpContext.User.Claims ,具体的你可以看看 Policys/PermissionHandler.cs 类中是如何使用的。 + */ + + + + new Claim(JwtRegisteredClaimNames.Jti, tokenModel.UserId.ToString()), + new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"), + new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") , + //这个就是过期时间,目前是过期1000秒,可自定义,注意JWT有自己的缓冲过期时间 + new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddDays(7)).ToUnixTimeSeconds()}"), + new Claim(ClaimTypes.Expiration, DateTime.Now.AddDays(1000).ToString()), + new Claim(JwtRegisteredClaimNames.Iss,iss), + new Claim(JwtRegisteredClaimNames.Aud,aud), + new Claim(JwtRegisteredClaimNames.Name,tokenModel.NickName), + + //new Claim(ClaimTypes.Role,tokenModel.Role),//为了解决一个用户多个角色(比如:Admin,System),用下边的方法 + }; + + // 可以将一个用户的多个角色全部赋予; + // 作者:DX 提供技术支持; + // claims.AddRange(tokenModel.Role.Split(',').Select(s => new Claim(ClaimTypes.Role, s))); + + + + //秘钥 (SymmetricSecurityKey 对安全性的要求,密钥的长度太短会报出异常) + var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)); + var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); + + var jwt = new JwtSecurityToken( + issuer: iss, + claims: claims, + signingCredentials: creds); + + var jwtHandler = new JwtSecurityTokenHandler(); + var encodedJwt = jwtHandler.WriteToken(jwt); + + return encodedJwt; + } + + + } /// @@ -115,4 +170,27 @@ namespace New_College.AuthHelper.OverWrite public string Work { get; set; } } + + public class SSOTokenModelJwt + { + /// + /// 用户Id + /// + public string UserId = "UserId"; + + + + /// + /// 昵称 + /// + public string NickName = "NickName"; + + + + /// + /// 登录模式PC、APP + /// + public string LoginMode = "LoginMode"; + } + } diff --git a/New_College.Model/Models/V_CustomerInfo.cs b/New_College.Model/Models/V_CustomerInfo.cs index a6eb6f7..4f5e8bc 100644 --- a/New_College.Model/Models/V_CustomerInfo.cs +++ b/New_College.Model/Models/V_CustomerInfo.cs @@ -2,6 +2,7 @@ using SqlSugar; using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Text; namespace New_College.Model.Models @@ -26,6 +27,13 @@ namespace New_College.Model.Models [SugarColumn(IsNullable = true)] public string OpenId { get; set; } + + /// + /// 公众号openid + /// + [SugarColumn(IsNullable = true)] + public string GZOpenId { get; set; } + /// /// 用户名 /// @@ -106,6 +114,7 @@ namespace New_College.Model.Models public string Subjectgroup { get; set; } + /// /// /// @@ -144,7 +153,7 @@ namespace New_College.Model.Models /// - /// CasdoorId + /// UnionId /// [SugarColumn(IsNullable = true)] public string UUID { get; set; } diff --git a/New_College.Model/Request/DecryptUserInfoRequest.cs b/New_College.Model/Request/DecryptUserInfoRequest.cs index 55b7e16..51c6631 100644 --- a/New_College.Model/Request/DecryptUserInfoRequest.cs +++ b/New_College.Model/Request/DecryptUserInfoRequest.cs @@ -7,7 +7,7 @@ namespace New_College.Model.Request { public class DecryptUserInfoRequest : GetPhoneInfo { - + public string UnionId { get; set; } /// /// 用户头像 /// diff --git a/New_College.Model/Request/LoginQuery.cs b/New_College.Model/Request/LoginQuery.cs index ed3f27b..4d4efa2 100644 --- a/New_College.Model/Request/LoginQuery.cs +++ b/New_College.Model/Request/LoginQuery.cs @@ -15,6 +15,9 @@ namespace New_College.Model.Request /// 退出重新登录时传此值 /// public string code { get; set; } + + public string unionId { get; set; } + } diff --git a/New_College.Model/ResponseEnum.cs b/New_College.Model/ResponseEnum.cs index 70a02ae..54c1a45 100644 --- a/New_College.Model/ResponseEnum.cs +++ b/New_College.Model/ResponseEnum.cs @@ -20,4 +20,45 @@ namespace New_College.Model [Description("服务器错误")] ServerError = 500 } + + public enum PlatformTypeEnum + { /// + /// 微信公众号 + /// + [Description("微信公众号")] + 微信公众号 = 1, + + /// + /// 微信小程序 + /// + [Description("微信小程序")] + 微信小程序 = 2, + + /// + /// QQ + /// + [Description("QQ")] + QQ = 3, + + /// + /// 支付宝 + /// + [Description("支付宝")] + Alipay = 4, + } + public enum LoginModeEnum + { + /// + /// PC模式 + /// + [Description("PC模式")] + PC = 1, + + /// + /// APP + /// + [Description("APP")] + APP = 2 + } + } diff --git a/New_College.Model/ViewModels/Result/CasDoorTokenResult.cs b/New_College.Model/ViewModels/Result/CasDoorTokenResult.cs index b31516d..55a865a 100644 --- a/New_College.Model/ViewModels/Result/CasDoorTokenResult.cs +++ b/New_College.Model/ViewModels/Result/CasDoorTokenResult.cs @@ -16,11 +16,91 @@ namespace New_College.Model.ViewModels public string error_description { get; set; } } + public class JWTSSOResult + { + public int code { get; set; } + public string type { get; set; } + public string message { get; set; } + public T result { get; set; } + public object extras { get; set; } + public string time { get; set; } + } + public class MinProWxOutPut + { + + /// + /// 系统用户Id + /// + public long Id { get; set; } + + /// + /// 平台类型 + /// + public PlatformTypeEnum PlatformType { get; set; } = PlatformTypeEnum.微信公众号; + + /// + /// OpenId + /// + public string OpenId { get; set; } + + /// + /// UnionId + /// + public string? UnionId { get; set; } + + /// + /// 昵称 + /// + public string? NickName { get; set; } + + /// + /// 头像 + /// + public string? Avatar { get; set; } + + /// + /// 手机号码 + /// + public string? Mobile { get; set; } + + /// + /// 性别 + /// + public int? Sex { get; set; } + + /// + /// 语言 + /// + public string? Language { get; set; } + + /// + /// 城市 + /// + + public string? City { get; set; } + + /// + /// 省 + /// + public string? Province { get; set; } + + /// + /// 国家 + /// + public string? Country { get; set; } + + /// + /// 租户Id + /// + public long? TenantId { get; set; } + + } + public class CasdoorRequest { - public string grant_type { get; set; } + //public string grant_type { get; set; } public string client_id { get; set; } public string client_secret { get; set; } public string code { get; set; } @@ -29,7 +109,7 @@ namespace New_College.Model.ViewModels public class CasDoorUpdatePwdDto { public string openId { get; set; } - + public string newPassword { get; set; } public string service_token { get; set; } diff --git a/New_College.Services/V_CustomerInfoServices.cs b/New_College.Services/V_CustomerInfoServices.cs index efbeff1..bce22df 100644 --- a/New_College.Services/V_CustomerInfoServices.cs +++ b/New_College.Services/V_CustomerInfoServices.cs @@ -595,10 +595,16 @@ namespace New_College.Services var userinfo = (await _dal.Query(w => w.OpenId == query.openId && w.IsDelete == false)).ToList().FirstOrDefault(); if (userinfo != null) { - if (!userinfo.IsVIP) + if (string.IsNullOrWhiteSpace(userinfo.UUID)) { - await SyncXET(userinfo); + userinfo.UUID = query.unionId; + await _dal.Update(userinfo); } + + //if (!userinfo.IsVIP) + //{ + // await SyncXET(userinfo); + //} return new Tuple(true, new CustomerInfoResult() { AreaId = userinfo.AreaId, @@ -680,7 +686,8 @@ namespace New_College.Services var i = await _dal.Add(new V_CustomerInfo() { OpenId = register.openid, - CustomerType = CustomerTypeEnum.General + CustomerType = CustomerTypeEnum.General, + UUID=register.UnionId }); return i; }