SignalR 是一个用于构建实时 Web 功能的 ASP.NET 库,它允许服务器端代码即时向连接的客户端推送内容。跨域调用是指客户端 JavaScript 代码从一个域向另一个域发起请求。
首先需要在 Startup.cs 中配置 SignalR 支持跨域:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", builder => builder
.WithOrigins("http://example.com") // 允许的源
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()); // 允许凭据
});
services.AddSignalR();
}
public void Configure(IApplicationBuilder app)
{
app.UseCors("CorsPolicy");
app.UseSignalR(routes =>
{
routes.MapHub<ChatHub>("/chatHub");
});
}
// Startup.cs
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
// 在 Hub 中使用
[Authorize]
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
// Startup.cs
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Jwt:Issuer"],
ValidAudience = Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
};
// SignalR 的 JWT 配置
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) &&
path.StartsWithSegments("/chatHub"))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
});
const connection = new signalR.HubConnectionBuilder()
.withUrl("http://yourdomain.com/chatHub", {
accessTokenFactory: () => {
// 返回你的 token (从 cookie 或 localStorage 获取)
return localStorage.getItem('token');
},
transport: signalR.HttpTransportType.WebSockets
})
.configureLogging(signalR.LogLevel.Information)
.build();
connection.start().then(() => {
console.log("连接成功");
}).catch(err => {
console.error(err.toString());
});
问题1:跨域请求被阻止
.AllowCredentials()
和 .WithOrigins()
都正确配置问题2:身份验证失败
问题3:WebSocket 连接失败
AllowAnyOrigin()
通过以上配置,你可以在 ASP.NET MVC 应用中实现 SignalR 的跨域调用并确保身份验证安全。
没有搜到相关的文章