Websocket传递JWT令牌

在访问带有[Authorize]的方法的时候,需要前端通过自定义报文头的形式将JWT令牌传递给后端进行验证,否则是不能访问带有[Authorize]的方法。

Authorize\]是用于限制对web应用程序中某些操作或控制器的访问。当\[授权\]属性应用于操作或控制器时,它表示用户必须经过身份验证和授权才能访问该特定资源。还可以使用其他参数自定义此属性,以根据特定角色或策略进一步限制访问。

但是Websocket是不支持自定义报文头的,所以我们只能通过url将JWT令牌进行传递。

这里创建了一个实现SignalR的方法,该方法带有[Authorize],功能是前端传递什么返回什么。

cs 复制代码
public class Myhub : Hub
{
    [Authorize]
    public Task SendPublicMsg(string msg)
    {
        string msgToSend = msg;
        return Clients.All.SendAsync("publicMsgReceived", msgToSend);
    }
}

在Program.cs中的配置

cs 复制代码
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

//JWT配置
builder.Services.Configure<JWTSettings>(builder.Configuration.GetSection("JWT"));
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(opt =>
{
    var jwtSettings = builder.Configuration.GetSection("JWT").Get<JWTSettings>();
    byte[] keyBytes = Encoding.UTF8.GetBytes(jwtSettings.SecKey);
    var secKey = new SymmetricSecurityKey(keyBytes);
    opt.TokenValidationParameters = new()
    {
        ValidateIssuer=false,
        ValidateAudience=false,
        ValidateLifetime=true,
        ValidateIssuerSigningKey=true,
        IssuerSigningKey=secKey
    };
    opt.Events = new JwtBearerEvents
    {
        //Websocket不支持自定义报文头
        OnMessageReceived = context =>
        {
            var accessToke = context.Request.Query["access_token"];//取出JWT
            var path = context.Request.Path;
            if (!string.IsNullOrEmpty(accessToke) && path.StartsWithSegments("/Myhub"))
            {
                context.Token = accessToke;
            }
            return Task.CompletedTask;
        }
    };
});

builder.Services.AddSignalR();//调用SignalR
builder.Services.AddMemoryCache();
cs 复制代码
app.UseCors();

app.UseHttpsRedirection();

app.UseAuthentication();

app.UseAuthorization();

app.MapHub<Myhub>("/Myhub");

app.MapControllers();

app.Run();

前端

界面

javascript 复制代码
<div>
	<button @click="JwtItem">连接</button>
	<button @click="sendMessage">发送</button>
	<input type="text" v-model="sigtext"/>
	<p v-for="i in msgs">{{i}}</p>
</div>

该连接要在后端返回你的JWT令牌后进行连接

javascript 复制代码
startConnection() {
	var options={skipNegotiation:true,transport:signalR.HttpTransportType.WebSockets};
    //this.JWTkey你的JWT令牌
	options.accessTokenFactory=()=>this.JWTkey;
	//创建连接
	this.connection = new signalR.HubConnectionBuilder()
	//大括号里面强制执行Websockets通道(解决分布式问题)
	    .withUrl('https://localhost:44334/Myhub',options) 
	    .withAutomaticReconnect() //断开自动连接
	    .build();
					
	//注册
	this.connection.on('publicMsgReceived', res=>{
		this.msgs.push(res)
	});
				
	//开始连接
	this.connection.start();
	},
JwtItem(){
		this.startConnection();//调用startConnection方法
	},
//调用后端方法
sendMessage() {
	//传递数据
	this.connection.invoke('SendPublicMsg', this.sigtext)
}

启动连接,我们可以看到JWT令牌通过url中的QueryString传递。

相关推荐
Macbethad6 小时前
基于WPF的Ethernet/IP主站程序技术方案
网络协议·tcp/ip·wpf
ganshenml7 小时前
【Web】证书(SSL/TLS)与域名之间的关系:完整、通俗、可落地的讲解
前端·网络协议·ssl
世界尽头与你7 小时前
SSL 签名相关漏洞
网络·安全·ssl
q***61417 小时前
Java实战:Spring Boot实现WebSocket实时通信
java·spring boot·websocket
合作小小程序员小小店7 小时前
桌面开发,在线%物品代送,代接管理%系统,基于vs2022,c#,winform,sql server数据。
开发语言·数据库·sql·microsoft·c#
g***B7387 小时前
Rust在网络中的Tokio
开发语言·网络·rust
这是个栗子7 小时前
npm报错 : 无法加载文件 npm.ps1,因为在此系统上禁止运行脚本
前端·npm·node.js
HIT_Weston8 小时前
44、【Ubuntu】【Gitlab】拉出内网 Web 服务:http.server 分析(一)
前端·ubuntu·gitlab
xu_yule8 小时前
网络和Linux网络-5(应用层)HTTP协议(方法+报头+状态码)
linux·网络·网络协议·http
报错小能手8 小时前
TCP/UDP面经整理
网络·tcp/ip·udp