IdentityServer4 + SignalR Core +RabbitMQ 构建web即时通讯(二)
IdentityServer4 + SignalR Core +RabbitMQ 构建web即时通讯(二)
IdentityServer4 用户中心生成数据库
上文已经创建了所有的数据库上下文迁移代码,这里开始数据库的迁移和种子数据,EF Core 2.1刚好新增了种子数据的功能,文档地址,一开始的想法是使用这种方式,看起来很简洁与方便,但需要在OnModelCreating中配置,不过IdentityServer4中的2个数据库上下文我不知道怎么配置进去了,所以还是用比较原始的方式吧。
1.在SeedData添加客户端Client ApiResource IdentityRecouse的种子数据;
public static List<Client> Clients()
{
return new List<Client>
{
new Client{
// 客户端id
ClientId ="chat_client",
// 客户端名称
ClientName ="chat client",
// TOKEN有效时长
AccessTokenLifetime = ,
// 配置TOKEN类型,reference为引用类型,数据不会存在TOKEN中
AccessTokenType= AccessTokenType.Jwt,
// 配置客户端授权模式
AllowedGrantTypes= GrantTypes.ResourceOwnerPassword,
// 配置客户端连接密码
ClientSecrets={ new Secret("".Sha256())},
// 客户端允许的请求范围
AllowedScopes={
"chatapi",
IdentityServerConstants.StandardScopes.OfflineAccess,
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile },
//允许离线,即开启refresh_token
AllowOfflineAccess =true,
RequireClientSecret=false
}
};
} public static IEnumerable<ApiResource> ApiResources()
{
return new List<ApiResource>
{
// 定义api资源 这里如果使用构造函数传入Name会默认创建一个同名的Scope,
// 这点需要注意,因为这个Api如果没有Scope,那根本无法访问
new ApiResource
{
Name="chatapi",
DisplayName="chat api",
ApiSecrets= { new Secret("".Sha256()) },
Scopes={
new Scope("chatapi","chat api")
}
}
};
} public static IEnumerable<IdentityResource> IdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile()
};
}
2.StartUp中增加迁移方法,Database.Migrate() 实际就是Update-Database命令,那为什么这样用呢?生产环境总不能让我去执行Update-Database吧?,当我们修改了实体代码与配置时,不用做任何处理,程序运行时就能自动更新数据库结构。Configure中调用 Migration(app).Wait();
public static async Task Migration(IApplicationBuilder app)
{
using (var scope = app.ApplicationServices.CreateScope())
{
// 迁移DemoDbContext上下文
scope.ServiceProvider.GetRequiredService<DemoDbContext>().Database.Migrate();
// 迁移PersistedGrantDbContext上下文
scope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();
var configurationDbContext = scope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();
// 迁移ConfigurationDbContext上下文
configurationDbContext.Database.Migrate(); // 注入用户管理 增加用户
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<DemoUser>>();
foreach (var user in SeedData.Users())
{
if (userManager.FindByNameAsync(user.UserName).Result == null)
{
await userManager.CreateAsync(user, "");
}
} // 增加ApiResources IdentityResources Clients
if (!configurationDbContext.ApiResources.Any())
configurationDbContext.ApiResources.AddRange(SeedData.ApiResources().Select(r => r.ToEntity()));
if (!configurationDbContext.IdentityResources.Any())
configurationDbContext.IdentityResources.AddRange(SeedData.IdentityResources().Select(r => r.ToEntity()));
if (!configurationDbContext.Clients.Any())
configurationDbContext.Clients.AddRange(SeedData.Clients().Select(r => r.ToEntity()));
await configurationDbContext.SaveChangesAsync();
}
}
这里有个不算坑的坑,Add-Migration命令创建迁移代码时需要把Migration(app).Wait()注释掉,为什么呢?这个命令实际上会启动应用,并执行里面的代码,当首次执行时,数据库并不存在,迁移代码也不存在,所以数据结构都还不存在,如果执行种子数据操作肯定会失败了,当然Add-Migration本身就算是一个代码生成器,属于开发时操作,所以这是一个不算坑的坑。
4.启动程序,控制台能看到迁移信息,

好了,数据库已经给我们创建好了

看看AspNetUsers,用户数据也没问题

现在打开Postman,用laowang这个用户试一试token能否拿到,token获取的地址为/connect/token,刷新token也是这个地址

没问题,我们把token复制下拿到jwt.io看看是否带有用户信息,

可以看到username,email,avatar,没有问题。
好了,这篇就到这,下一篇开始写聊天室后端服务。
IdentityServer4 + SignalR Core +RabbitMQ 构建web即时通讯(二)的更多相关文章
- IdentityServer4 + SignalR Core +RabbitMQ 构建web即时通讯(三)
IdentityServer4 + SignalR Core +RabbitMQ 构建web即时通讯(三) 后台服务用户与认证 新建一个空的.net core web项目Demo.Chat,端口配置为 ...
- IdentityServer4 + SignalR Core +RabbitMQ 构建web即时通讯(一)
IdentityServer4 + SignalR Core +RabbitMQ 构建web即时通讯 前言 .net core 2.1已经正式发布了,signalr core1.0随之发布,是时候写个 ...
- 一套简单的web即时通讯——第一版
前言 我们之前已经实现了 WebSocket+Java 私聊.群聊实例,后面我们模仿layer弹窗,封装了一个自己的web弹窗 自定义web弹窗/层:简易风格的msg与可拖放的dialog,生成博客园 ...
- web即时通讯2--基于Spring websocket达到web聊天室
如本文所用,Spring4和websocket要构建web聊天室,根据框架SpringMVC+Spring+Hibernate的Maven项目,后台使用spring websocket进行消息转发和聊 ...
- 为什么 web 开发人员需要迁移到. NET Core, 并使用 ASP.NET Core MVC 构建 web 和 webservice/API
2018 .NET开发者调查报告: .NET Core 是怎么样的状态,这里我们看到了还有非常多的.net开发人员还在观望,本文给大家一个建议.这仅代表我的个人意见, 我有充分的理由推荐.net 程序 ...
- 利用Eclipse中的Maven构建Web项目(二)
利用Eclipse中的Maven构建Web项目 1.新建源文件夹,Java Resources鼠标右键,"New-->Source Folder" 2.新建src/main/ ...
- 使用 ASP.NET Core MVC 创建 Web API(二)
使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 六.添加数据库上下文 数据库上下文是使用Entity Framewor ...
- .Net core 3.0 SignalR+Vue 实现简单的即时通讯/聊天IM (无jq依赖)
.Net core 中的SignalR JavaScript客户端已经不需要依赖Jquery了 一.服务端 1.nuget安装 Microsoft.AspNetCore.SignalR 2.在star ...
- Mysql EF Core 快速构建 Web Api
(1)首先创建一个.net core web api web项目; (2)因为我们使用的是ef连接mysql数据库,通过NuGet安装MySql.Data.EntityFrameworkCore,以来 ...
随机推荐
- 用cflow工具生成代码函数调用关系【转】
转自:http://www.cnblogs.com/feng-zi/p/5469652.html . 安装 sudo apt-get install cflow .使用 cflow [options. ...
- [转]在Storyboard中使用自定义的segue类型
转自:http://my.oschina.net/u/728866/blog/92709 我们知道segue共有三种类型:push.modal以及custom.如下图: 很明显,这三种类型的作用分 ...
- AC日记——宠物收养所 bzoj 1208
1208 思路: 一棵splay树: 如果来者是宠物且树空,就将其加入树中: 如果树不空,则查找前驱后继,取最优,然后删点: 对人亦然: 注意边界和取模,最后的ans用long long其余用int即 ...
- HDU 5135.Little Zu Chongzhi's Triangles-字符串 (2014ACM/ICPC亚洲区广州站-重现赛)
Little Zu Chongzhi's Triangles Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 512000/512000 ...
- Codeforces 158 B. Taxi[贪心/模拟/一辆车最多可以坐4人同一个群的小朋友必须坐同一辆车问最少需要多少辆车]
http://codeforces.com/problemset/problem/158/B B. Taxi time limit per test 3 seconds memory limit pe ...
- 如何证明一个数的数根(digital root)就是它对9的余数?
数根就是不断地求这个数的各位数之和,直到求到个位数为止.所以数根一定和该数模9同余,但是数根又是大于零小于10的,所以数根模9的余数就是它本身,也就是说该数模9之后余数就是数根. 证明: 假设有一个n ...
- 不一样视角的Glide剖析
推荐阅读: 滴滴Booster移动App质量优化框架-学习之旅 一 Android 模块Api化演练 不一样视角的Glide剖析(一) Glide是一个快速高效的Android图片加载库,注重于平滑的 ...
- [USACO15JAN]踩踏Stampede
[USACO15JAN]踩踏Stampede 题目描述 DJ站在原点上向y轴正半轴看,然后有一群奶牛从他眼前飞过.这些奶牛初始都在第二象限,尾巴在(Xi,Yi),头在(Xi+1,Yi),每Ci秒向右走 ...
- workflow engine Ruote初体验之一(概念)
由于最近自己写点小东西,需要有工作流程管理方面的应用,所有的环境为Ruby on rails,所有在选择流程引擎的时候选择了ruote,但是对于ruote是完全陌生的,所以在这里记下点滴,如果理解的不 ...
- Linux下监听或绑定(bind)21端口失败
问题:写了一个程序,尝试在21端口监听,结果在执行bind的时候失败了. sockaddr_in sock_addr; sock_addr.sin_family = AF_INET; sock_add ...