Clojure: как аутентифицировать пользователя веб-сокета? - PullRequest
0 голосов
/ 02 мая 2020

Я следовал за примером http-kit websockets и позже застрял, пытаясь найти идиоматический c способ сопоставления каналов WS пользователям на бэкэнде.

У меня есть попытался проверить объект org.httpkit.server.AsyncChannel, используя отражение Java, и получил следующие атрибуты:

|                           :name |         :return-type |                :declaring-class |                                               :parameter-types |      :exception-types |              :flags |
|---------------------------------+----------------------+---------------------------------+----------------------------------------------------------------+-----------------------+---------------------|
|                       chunkSize |  java.nio.ByteBuffer | org.httpkit.server.AsyncChannel |                                                          [int] |                    [] | #{:private :static} |
|                      firstWrite |                 void | org.httpkit.server.AsyncChannel |                                     [java.lang.Object boolean] | [java.io.IOException] |         #{:private} |
|                        isClosed |              boolean | org.httpkit.server.AsyncChannel |                                                             [] |                    [] |          #{:public} |
|                     isWebSocket |              boolean | org.httpkit.server.AsyncChannel |                                                             [] |                    [] |          #{:public} |
|                 messageReceived |                 void | org.httpkit.server.AsyncChannel |                                             [java.lang.Object] |                    [] |          #{:public} |
|                         onClose |                 void | org.httpkit.server.AsyncChannel |                                                          [int] |                    [] |          #{:public} |
| org.httpkit.server.AsyncChannel |                      | org.httpkit.server.AsyncChannel | [java.nio.channels.SelectionKey org.httpkit.server.HttpServer] |                    [] |          #{:public} |
|                    pingReceived |                 void | org.httpkit.server.AsyncChannel |                                                       [byte<>] |                    [] |          #{:public} |
|                        readable | clojure.lang.Keyword | org.httpkit.server.AsyncChannel |                                                          [int] |                    [] | #{:private :static} |
|                           reset |                 void | org.httpkit.server.AsyncChannel |                               [org.httpkit.server.HttpRequest] |                    [] |          #{:public} |
|                            send |              boolean | org.httpkit.server.AsyncChannel |                                     [java.lang.Object boolean] | [java.io.IOException] |          #{:public} |
|                   sendHandshake |                 void | org.httpkit.server.AsyncChannel |                                                [java.util.Map] |                    [] |          #{:public} |
|                     serverClose |              boolean | org.httpkit.server.AsyncChannel |                                                          [int] |                    [] |          #{:public} |
|                 setCloseHandler |                 void | org.httpkit.server.AsyncChannel |                                             [clojure.lang.IFn] |                    [] |          #{:public} |
|                  setPingHandler |                 void | org.httpkit.server.AsyncChannel |                                             [clojure.lang.IFn] |                    [] |          #{:public} |
|               setReceiveHandler |                 void | org.httpkit.server.AsyncChannel |                                             [clojure.lang.IFn] |                    [] |          #{:public} |
|                        toString |     java.lang.String | org.httpkit.server.AsyncChannel |                                                             [] |                    [] |          #{:public} |
|                      writeChunk |                 void | org.httpkit.server.AsyncChannel |                                     [java.lang.Object boolean] | [java.io.IOException] |         #{:private} |
nil

, которые, кажется, не содержат четких идентификаторов, включая .toString:

user=> (.toString ch)
"/0:0:0:0:0:0:0:1:3000<->/0:0:0:0:0:0:0:1:54538"

Единственная идея, которую я мог придумать, заключается в следующем:

1) Сохранить connect! функцию как есть:

(defonce channels (atom #{}))

(defn connect! [channel]
  (log/info "channel open" channel)
  (swap! channels conj channel))

2) Обновить клиент WebSocket для отправки JWT или вызов идентификатора сеанса в качестве первого сообщения сразу после установления соединения WS, которое позволяет сопоставить этот (уже установленный) канал с идентификатором (JWT или идентификатором сеанса вызова), который может идентифицировать пользователя.

Имеет ли это смысл при все? Или это большой антипаттерн и нарушение WS RFC? Извините, я не работал с WebSockets на таком низком уровне раньше.

...