.NET Core+QQ第三方授权登录 (2)

用户授权信息表,用于存储不同登录类型的用户信息,如手机号、邮件、用户名、第三方应用(微信、QQ、GitHub)的登录

字段 类型 备注
Id   long   主键  
IdentityType   varchar(50)   认证类型,如 Password,GitHub、QQ、WeiXin等  
Identifier   varchar(24)   认证者,例如 用户名(PassWord认证类型),授权得到的昵称(QQ),授权得到的用户名(唯一,GitHub)  
Credential   varchar(50)   凭证,例如 密码,存OpenId、Id,同一IdentityType的OpenId的值是唯一的  
CreateUserId   long   绑定的用户Id  

根据openId,判断lin_user_identity表中是否存在这一第三方授权信息,如果存在,则返回当前用户lin_user表中的id,如果不存在,则创建一个新的用户信息,插入lin_user、lin_user_identity表中。

public async Task<long> SaveQQAsync(ClaimsPrincipal principal, string openId) { string nickname = principal.FindFirst(ClaimTypes.Name)?.Value; string gender = principal.FindFirst(ClaimTypes.Gender)?.Value; string picture = principal.FindFirst(QQAuthenticationConstants.Claims.PictureUrl)?.Value; string picture_medium = principal.FindFirst(QQAuthenticationConstants.Claims.PictureMediumUrl)?.Value; string picture_full = principal.FindFirst(QQAuthenticationConstants.Claims.PictureFullUrl)?.Value; string avatar = principal.FindFirst(QQAuthenticationConstants.Claims.AvatarUrl)?.Value; string avatar_full = principal.FindFirst(QQAuthenticationConstants.Claims.AvatarFullUrl)?.Value; Expression<Func<LinUserIdentity, bool>> expression = r => r.IdentityType == LinUserIdentity.QQ&& r.Credential == openId; LinUserIdentity linUserIdentity =await _userIdentityRepository.Where(expression).FirstAsync(); long userId = 0; if (linUserIdentity == null) { LinUser user = new LinUser { Avatar = avatar_full, Nickname = nickname, Username = "", LinUserIdentitys = new List<LinUserIdentity>() { new LinUserIdentity { CreateTime = DateTime.Now, Credential = openId, IdentityType = LinUserIdentity.GitHub, Identifier = nickname, } } }; await _userRepository.InsertAsync(user); userId = user.Id; } else { userId = linUserIdentity.CreateUserId; } return userId; }

上文中的CreateToken,直接将 authenticateResult.Principal.Claims.ToList(),生成token值,会缺少一些系统需要的值,比如键为ClaimTypes.NameIdentifier,应为用户的id,用户的其他信息,如角色/分组,昵称。不同平台的授权登录,键有所不同,所以这里需要二次处理。

[HttpGet("signin-callback")] public async Task<IActionResult> Home(string provider, string redirectUrl = "") { //xxx ClaimsPrincipal principal=authenticateResult.Principal; List<Claim> authClaims = principal.Claims.ToList(); long id =SaveQQAsync(principal, openIdClaim.Value) LinUser user =await _userRepository.Select.IncludeMany(r => r.LinGroups) .WhereCascade(r => r.IsDeleted == false).Where(r => r.Id == id).FirstAsync(); List<Claim> claims = new List<Claim>() { new Claim(ClaimTypes.NameIdentifier,user.Id.ToString()), new Claim(ClaimTypes.GivenName,user.Nickname??""), new Claim(ClaimTypes.Name,user.Username??""), }; user.LinGroups?.ForEach(r => { claims.Add(new Claim(LinCmsClaimTypes.Groups, r.Id.ToString())); }); claims.AddRange(authClaims); string token = this.CreateToken(claims); return Redirect($"{redirectUrl}?token={token}#login-result"); }

前台login-result路由,解析到token值,并保存起来,与用户密码登录后的流程相同。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zywsfx.html