Как добавить cookie в заголовок через Django Channels? - PullRequest
0 голосов
/ 27 апреля 2019

В моем интерфейсе у меня есть следующая конфигурация.Аутентификация выполняется вручную, потому что реагировать не удается при наличии постоянных сеансов:

...
const authLink = setContext(request =>
  storage.getCookie().then(cookie => ({
    // Before the request is sent: set cookie header
    headers: {
      cookie,
    },
    credentials: 'omit', // set cookies manually
  }))
)

const setTokenLink = new ApolloLink((operation, forward) => {
  // Send the request to the server
  return forward(operation).map(response => {
    // After response is returned: store cookie in local storage
    const context = operation.getContext()
    const {
      response: { headers },
    } = context

    if (headers) {
      storage.setCookie(headers.get('set-cookie'))
    }

    return response
  })
})
storage.getCookie().then(cookie => console.log(cookie))
// console.log('cookie', storage.getCookie().then(cookie => {cookie}))

const httpLink = createUploadLink({
  uri: `${domainApi}/graphql/`,
})

const wsClient = new SubscriptionClient(
  domainWs,
  {
    lazy: true,
    reconnect: true,
    connectionParams: {
      authToken: storage.getCookie(),
    },
  })
)
...

Тем не менее это влияет на веб-сокеты, потому что в бэкэнде заголовки не содержат cookie.

class GraphqlSubcriptionConsumer(SyncConsumer):
    def __init__(self, scope):
        super().__init__(scope)
        self.subscriptions = {}
        self.groups = {}

    def websocket_connect(self, message):
        self.send({"type": "websocket.accept", "subprotocol": "graphql-ws"})

    def websocket_disconnect(self, message):
        for group in self.groups.keys():
            group_discard = async_to_sync(self.channel_layer.group_discard)
            group_discard(f"django.{group}", self.channel_name)

        self.send({"type": "websocket.close", "code": 1000})
        raise StopConsumer()

    def websocket_receive(self, message):
        request = json.loads(message["text"])
        id = request.get("id")

        if request["type"] == "connection_init":
            return

        elif request["type"] == "start":
            print("scope user:", self.scope["user"]) //returns AnonymousUser
            print("scope headers:", self.scope["headers"]) //returns headers without the cookie
...

В этой конфигурации я получаю

{'type': 'websocket.receive', 'text': '{"type":"connection_init","payload":{"authToken":{"_40":0,"_65":1,"_55":"sessionid=bci028bzn1cgxyuynvb7fjevc5ynqdil","_72":null}}}'}

при каждом первом сообщении с типом connection_init.Поэтому мне было интересно, есть ли способ вручную вставить cookie в django (возможно, в if request["type"] == "connection_init":) в область видимости, чтобы последующие сообщения типа start содержали cookie.

Любой небольшой совет /подсказка помогает.

...