欢迎光临散文网 会员登陆 & 注册

10)ABP实现集成openiddict的第三方授权登录(github)&UI授权登录

2022-11-16 10:45 作者:紫檀清香  | 我要投稿

上章我们已经可以请求获取到了授权用户的信息,只不过没有把信息暂存到实体中。

由于我们是多平台的授权登录,每个平台之间返回的数据类型有所差异,所有这里统一定义了我需要的核心数据 AuthUserBaseInfo,同时平台之间返回的字段差异需要有地方映射 AuthUserBaseInfo里面字段,进而定义了 IAuthUserInfoFieldMap的 FieldMap()方法, 代码如下:

在 YiAim.Cms.Application.Contracts里面新建


github通过授权获取的用户信息转换成功GithubAuthDto

可以看到github里面返回的没有是login字段,没有UserName,所有这里我将login赋值给UserName。同时在FieldMap里面赋值给了NickName(因为在github里面返回没有找到合适的字段)


在 YiAim.Cms.Application 里面的 GithubService 修改返回类型


在 ThirdOAuthServiceBase 抽象类里面的 GetUserByOAuthAsync方法为AccessToken属性赋值

    


AuthorizeService里面,实现了IAuthorizeService相关的接口,最后返回用户信息时一定要调用FieldMap(),统一映射AuthUserBaseInfo对象

 


实现的效果

实现的效果

接下来进行数据迁移生成第三方授权表AppUserThirdAuth,同时将curd的方法补齐。

切到vue项目里面

先把登录页面的第三方授权登录入口加入

   

在src\identity里新建auth.js

auth.js

去到github里面将跳转回调地址改成 http://localhost:9527/#auth-redirect 跳转回到vue项目里面,同时不要忘记看看vue里面对应的路由是否存在,不存在则补上;permission.js里面要将auth-redirect放到whiteList数组里面解除验证。

github跳转回调

修改登录流程,通过openiddict的/connect/token完成第三方授权同时返回token

本来我是想像identityServer那样简单配置扩展登录项就可以了,事实证明我还是太年轻了。 先来看一下IdentityServer4通过/connect/token获取token

IdentityServer4通过GrantType来区分不同的授权方式,除了常规的授权方式之外,在defaut条件中,有自定义授权生成token的方式(ProcessExtensionGrantRequestAsync),可以通过这种方式集成其他方式验证比如:微信登陆、短信登陆等等;

简单实现如下:1、自定义授权实现继承IExtensionGrantValidator并实现ValidateAsync方法 2、添加扩展方法 3、种子数据添加grantTypes

核心代码如下


在配置中注入扩展方法


添加种子数据


通过上述方法就可以实现IdentityServer4的扩展登录,那么openiddict应该也支持扩展方式实现,在查看openiddict文档(https://documentation.openiddict.com/),我是没有找到类似IdentityServer4扩展方法。openiddict默认实现了五种获取token的方式。在文档中没有找到只能去看看一下源码,在abp源码里面打开openiddict的源码,发现确实是支持扩展的方式。

兴奋了一小会~ 开干,按照IdentityServer方式继续ITokenExtensionGrant实现一个类似。调试的时候发现都不触发,我是这样注入


也许是我的实现或者注入的方式错了,反正搞了两天尝试Google、百度搞了N种方式,最后直接放弃该方法。最后想直接修改源代码不是来得更简单,回到openiddict源码中发现 TokenController是个部分类同时HandleAsync是个虚拟方法允许重写。 在stackoverflow里面还发现别人很多年前使用Google Auth with OpenIdDictServer实现方式可以借鉴一下(https://stackoverflow.com/questions/41223694/rich-twitter-digits-google-auth-with-openiddictserver)

在YiAim.Cms.HttpApi里的Controllers新建YiAimTokenController,继承TokenController以保留原有的功能


这里要将路由重写不能使用原路由/connect/token,就算你将路由的order=-1一样不行。路由重写之后还需要 (CmsWebModule) ConfigureServices(ServiceConfigurationContext context)方法里面配置如下


SetTokenEndpointUri一定设置跟路由对应的,不然会出现错误An OpenID Connect response cannot be returned from this endpoint,我在stackoverflow得到解释: OpenIddict 配置了/connect/token作为令牌端点地址,如果地址与注册端点路径不同,OpenIddict不处理该请求并拒绝将其视为令牌请求 详情见(https://stackoverflow.com/questions/42048770/asp-net-core-openiddict-throws-an-openid-connect-response-cannot-be-returned-fr)

下面是我项目实现的逻辑代码,其他更多方式可以OpenIddict源码里面token的实现

回到vue里面把登录页面(src\views\index.vue)和src\store\user.js优化一下, index.vue里面账户密码登录和第三方授权登录都统一采用this.$store.dispatch("user/login", clientSetting)实现,store\user.js里面直接传参数进入。

最后来测试一下

测试前先要在openiddictapplications表中添加授权数据,可以直接在表中添加也可使用数据迁移方式添加

运行项目测试,可以看到直接提示为绑定xxx。这个结果就是正确的预期,因为第三方授权表里没有数据。第三方授权表的数据可以给定一个绑定界面从绑定界面写入绑定关系即可,这里就不实现了。

运行项目测试,可以看到直接提示为绑定

我直接从数据库里面添加一条我的GitHub绑定关系再看效果

GitHub绑定关系再看效果

总结

到此第三方github集成openiddict授权登录的功能&UI授权登录已经完成了。其中还有挺多的细节需要优化的比如:accesstoken的有效期(微信公众号的accesstoken为两个小时且一天之中有请求次数限制),实际项目中这些都是需要做处理的问题。在使用openiddict的过程中遇到了挺多的问题,加上openiddict的相关资料基本都是英文而且案例也少同时个人水平有限,所以难度又增加了亿点点。所幸的是花费了几天的时间终于完成了这个功能点。期待.NET的生态越来越好。



10)ABP实现集成openiddict的第三方授权登录(github)&UI授权登录的评论 (共 条)

分享到微博请遵守国家法律