簡體   English   中英

Spring + Oauth2 + JWT+ Websocket

[英]Spring + Oauth2 + JWT+ Websocket

我正在做一個關於 spring boot + oauth2 + websocket 的例子。 我在 8098 端口上運行的資源服務器上有 spring websocket 配置和其他代碼。 我試圖從在 8080 端口上運行的客戶端應用程序連接它。 但是當我運行我的應用程序時,我在瀏覽器控制台上收到錯誤 401(未經授權)。 我正在分享我的一些代碼:

1)客戶端應用程序(運行在8080端口)獲取websocket連接的javaScript代碼

'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”以解碼形式發送訪問令牌。

所以我做了一些調試,我開始知道令牌應該以其實際形式發送並且沒有解碼。

  1. 以前我在客戶端從這樣的響應中提取訪問令牌:

let decoded = jwt_decode(response.entity.details.tokenValue); localStorage.setItem("ACCESS_TOKEN", decoded.jti);

這是不正確的。 所以我用下面的代碼改變了它:

localStorage.setItem("ACCESS_TOKEN", response.entity.details.tokenValue);

  1. 在 websocket-listener js 文件中,我做了以下更改
const access_token = localStorage.getItem("ACCESS_TOKEN");

var socket = SockJS('http://localhost:8098/notifications/?access_token='+access_token);

並看到我在 url 查詢參數中發送訪問令牌,沒有前綴“承載”。

它奏效了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM