做了个web端程序,同步的钉钉用户,然后还有一个钉钉小程序的需求,钉钉小程序有个免登陆码,根据这个获取到dingUserId
对了,AbpUserLogins表要有对应的provider
providerKey 我对应的就是钉钉的userId
主要代码:
TokenAuthController.cs
代码:
/// <summary>
/// 钉钉小程序登录
/// </summary>
/// <param name="model">这个model 只是用到了 AuthCode和DomainName</param>
/// <returns></returns>
[HttpPost]
public async Task<AuthenticateResultModel> DingAuthenticate([FromBody] DingAuthenticateModel model)
{
var userInfo = _dingTalkService.GetUserInfoByAuthCode(model.AuthCode, model.DomainName);
var loginResult = await _logInManager.LoginAsync(new UserLoginInfo("DingMiniProgram", userInfo.DingTalkUserId, null),
"Default");
var accessToken = CreateAccessToken(CreateJwtClaims(loginResult.Identity));
return new AuthenticateResultModel
{
AccessToken = accessToken,
EncryptedAccessToken = GetEncryptedAccessToken(accessToken),
ExpireInSeconds = (int)_configuration.Expiration.TotalSeconds,
UserId = loginResult.User.Id
};
}
变动对比:
GetUserInfoByAuthCode 方法
/// <summary>
/// 根据AuthCode和租户域名获取用户信息
/// </summary>
/// <param name="authCode">小程序免登授权码</param>
/// <param name="domainName">根据域名获取当前租户</param>
/// <returns></returns>
public User GetUserInfoByAuthCode(string authCode, string domainName)
{
string getUserInfoApi = "https://oapi.dingtalk.com/user/getuserinfo";
IDingTalkClient client = new DefaultDingTalkClient(getUserInfoApi);
OapiUserGetuserinfoRequest req = new OapiUserGetuserinfoRequest();
req.SetHttpMethod("GET");
req.Code = authCode;
_currentTenant = _tenantManager.GetTenantByDomainName(domainName);
// 给全局的租户赋值,不然没法访问数据库
_unitOfWorkManager.Current.SetTenantId(_currentTenant.Id);
OapiUserGetuserinfoResponse rsp = client.Execute(req, AccessToken);
if (rsp.Errcode > 0)
{
Logger.Error($"获取用户信息:{rsp.Errmsg}");
throw new UserFriendlyException($"调用钉钉API {getUserInfoApi}报错:{rsp.Errmsg}");
}
// DingUserId,本地User表有对应的字段,可以根据这个标志位拿取数据库用户信息
if (!string.IsNullOrEmpty(rsp.Userid))
{
return _userManager.FindByDingTalkUserId(rsp.Userid);
}
return null;
}
GetTenantByDomainName和FindByDingTalkUserId 就是简单的过滤查询
DingAuthenticateModel文件:
测试截图:
如果你的钉钉用户有没有同步到数据的,那就需要钉钉登录的时候自动创建用户之类的,那就要在
public async Task<AuthenticateResultModel> DingAuthenticate([FromBody] DingAuthenticateModel model)
的
写注册逻辑,我是偷了个懒,在上面 userInfo 那直接创建了,后面就能保证都是 case AbpLoginResultType.Success:
百度搜相关的东西,都特么一个模子里的,各位盗窃别人文章的弟弟们,希望能保留原地址,不然爸爸会打你屁股的。