Spring + Oauth2 + JWT + Websocket
我正在做一个spring boot + oauth2 + websocket的例子。我在运行于8098端口的资源服务器上配置了spring websocket配置和其他代码。我试图从运行在8080端口上的客户端应用程序连接它。但是当我运行我的应用程序时,我在浏览器控制台上收到错误401(未授权)。我分享我的一些代码:Spring + Oauth2 + JWT + Websocket
1)客户端应用程序(在8080端口上运行)的JavaScript代码来获得WebSocket连接
'use strict';
// pull in the SockJS JavaScript library for talking over WebSockets.
var SockJS = require('sockjs-client');
// pull in the stomp-websocket JavaScript library to use the STOMP sub-protocol.
require('stompjs');
function register(registrations) {
const access_token = localStorage.getItem("ACCESS_TOKEN");
console.log("Access Token " + access_token);
const csrf_token = localStorage.getItem("XSRF");
// Here is where the WebSocket is pointed at the server application’s /messages endpoint
// websocket use this URL to open TCP connection
var socket = SockJS('http://localhost:8098/notifications');
var stompClient = Stomp.over(socket);
var headers = {
'X-Csrf-Token': csrf_token,
Authorization: 'Bearer ' + access_token
}
// connect to server using stompClient
stompClient.connect(headers, function(frame) {
// Iterate over the array of registrations supplied so each can subscribe for callback as messages arrive.
stompClient.send("/app/notifications", {});
registrations.forEach(function (registration) {
stompClient.subscribe(registration.route, registration.callback);
});
});
}
module.exports = {
register: register
};
2)资源服务器(8098端口)代码运行在那里我有服务器侧websocket配置
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration extends AbstractSecurityWebSocketMessageBrokerConfigurer {
// This prefix we will append to every message's route.
static final String MESSAGE_PREFIX = "/topic"
static final String END_POINT = "/notifications"
static final String APPLICATION_DESTINATION_PREFIX = "/app"
@Override
protected boolean sameOriginDisabled() {
return true;
}
/**
* This method configure the end-point on the backend for clients and server to link ('/notifications').
*/
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
// This code register the '/notifications' end-point. The SockJS client will attempt to connect to '/notifications' end-point
if(registry != null) {
registry.addEndpoint(END_POINT).setAllowedOrigins("*").withSockJS()
}
}
/**
* This method configure the message broker used to relay messages between server and client.
*/
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
if(registry != null) {
// Enable a broker to send messages to the client on destinations prefixed with '/topic'
registry.enableSimpleBroker(MESSAGE_PREFIX);
// prefix for messages that are bound for @MessageMapping annotated methods. This prefix will be used to define all message mappings
registry.setApplicationDestinationPrefixes(APPLICATION_DESTINATION_PREFIX)
}
}
}
请提出一些解决方案。
最后我解决了这个问题。问题是我以前使用jwt_token和前缀'bearer'以解码形式发送访问令牌。
所以我做了一些调试,我开始知道该令牌应该以实际的形式发送,而不需要解码。
- 以前我是在客户端从这样提取的响应访问令牌:
令解码= jwt_decode(response.entity.details.tokenValue); localStorage.setItem(“ACCESS_TOKEN”,decoded.jti);
这是不正确的。所以我改变它与下面的代码:
localStorage.setItem(“ACCESS_TOKEN”,response.entity.details.tokenValue);
- 在网页套接字侦听JS文件I下面做改变
常量=的access_token localStorage.getItem( “ACCESS_TOKEN”);
var socket = SockJS('http://localhost:8098/notifications/?access_token='+ access_token);
并且看到我在URL查询参数中发送访问令牌,但没有前缀'bearer'。
它工作。