django каналы Websocket, прошедший проверку подлинности на основе токенов, продолжает отключаться ERR_CONNECTION_RESET - PullRequest
0 голосов
/ 24 апреля 2020

я использую реагирование в качестве моего внешнего интерфейса и django в качестве моего бэкэнда, поэтому мне необходимо использовать аутентификацию на основе токенов с django каналами. Метод, который я использую, заключается в отправке токена аутентификации в виде заголовка cook ie. Методология была взята из этого git сообщения центра здесь

До сих пор я собрал большинство рабочих частей вместе, однако, кажется, я не могу сохранить связь , он всегда будет возвращать ошибку в моей консоли:

 ERR_CONNECTION_RESET

Вот мой код:

FRONTEND: Websocket. js

class WebSocketService{
static instance = null; 
callbacks = {};

static getInstance(){
    if (!WebSocketService.instance){
        WebSocketService.instance = new WebSocketService();
    }
    return WebSocketService.instance;
}

constructor(){
    this.socketRef = null;
}

connect(token){
    var loc = window.location
    var wsStart = 'ws://'
    if (loc.protocol === 'https'){
      wsStart = 'wss://'
    }
    const path = wsStart + 'localhost:8000'+ loc.pathname
    // console.log(path)
    // console.log(path + "?token=" + token)
    document.cookie = 'authorization=' + token + ';' 
    console.log(document.cookie)
    this.socketRef = new WebSocket(path)

    this.socketRef.onmessage = e => {
        console.log('in on message')
        this.socketNewMessage(e.data);
      };

    this.socketRef.onopen = () => {
        console.log(this.props.token)
        console.log("WebSocket open");
    };

    this.socketRef.onerror = e => {
        console.log('error happ')
        console.log(e.message);
    };

    this.socketRef.onclose = () => {
        console.log("WebSocket closed, restarting..");
        this.connect(token);
    };   
}

socketNewMessage(data){
    const parsedData = JSON.parse(data);
    const command = parsedData.command;
    if(Object.keys(this.callbacks).length === 0){
        return;
    }
    if(command === 'messages'){
        this.callbacks[command](parsedData.messages);
    }
    if(command === 'new_message'){
        console.log("okay so this was called")
        this.callbacks[command](parsedData.message);
    }
}

state(){
    return this.socketRef.readyState;
}
waitForSocketConnection(callback){
    const socket = this.socketRef;
    const recursion = this.waitForSocketConnection;
    setTimeout(
        function(){
            if(socket.readyState === 1){
                console.log("Connection is made");
                if(callback != null){
                    callback();
                }
                return;
            }
            else{
                console.log("Wait for connection..");
                recursion(callback);
            }
        }, 1);
}
}

    let WebSocketInstance = WebSocketService.getInstance();

    export default WebSocketInstance;

FRONTEND: Приложения . js

class App extends Component {

  componentDidMount() {
    console.log('app mounting..')
    this.props.onTryAutoSignup();
    console.log(this.props.isAuthenticated)
    if (this.props.isAuthenticated) {
      WebSocketInstance.connect()    
    }
  }

  componentDidUpdate(oldProps) {
    console.log('app updating props..')
    if (this.props.token !== oldProps.token ) {
      console.log(this.props.token)
      WebSocketInstance.connect(this.props.token)       
    }
  }

  render() {
    return (
      <div>
        <Router>
          <CustomLayout {...this.props}>
                <BaseRouter/>
          </CustomLayout>
        </Router>
      </div>
    );
  }
}

const mapStateToProps = state => {
  return {
    isAuthenticated: state.token !== null ,
    token : state.token
  }
}

const mapDispatchToProps = dispatch => {
  return {
    onTryAutoSignup: () => dispatch(actions.authCheckState())
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(App);

BACKEND: token_auth.py (пользовательское промежуточное ПО)

@database_sync_to_async
def get_user(token_key):
    try:
        return Token.objects.get(key=token_key).user
    except Token.DoesNotExist:
        return AnonymousUser()


class TokenAuthMiddleware:
    """
    Token authorization middleware for Django Channels 2
    see:
    https://channels.readthedocs.io/en/latest/topics/authentication.html#custom-authentication
    """

    def __init__(self, inner):
        self.inner = inner

    def __call__(self, scope):
        return TokenAuthMiddlewareInstance(scope, self)


class TokenAuthMiddlewareInstance:
    def __init__(self, scope, middleware):
        self.middleware = middleware
        self.scope = dict(scope)
        self.inner = self.middleware.inner

    async def __call__(self, receive, send):
        headers = dict(self.scope["headers"])
        print(headers[b"cookie"])
        if b"authorization" in headers[b"cookie"]:
            print('still good here')
            cookies = headers[b"cookie"].decode()
            token_key = re.search("authorization=(.*)(; )?", cookies).group(1)
            if token_key:
                self.scope["user"] = await get_user(token_key)

        return self.inner(self.scope)

BACKEND: Router.py

    application = ProtocolTypeRouter({
    "websocket": TokenAuthMiddlewareStack(
        URLRouter([
            path("", NotificationConsumer),
        ]),
    ),

})

TokenAuthMiddlewareStack = lambda inner: TokenAuthMiddleware(AuthMiddlewareStack(inner))

Вот мой элементы, которые были распечатаны в моей командной строке:

WebSocket HANDSHAKING / [127.0.0.1:59931]
b'authorization=xxxxxxxxxxxx' #<-- token from the cookie header
still good here #<--- passed first validation
user1  #<---- went into the get_user function i declared within my middleware
WebSocket DISCONNECT / [127.0.0.1:59931]   #<---- disconnects...

Пожалуйста, помогите! Я потерян!

1 Ответ

0 голосов
/ 24 апреля 2020

проблема была с экземпляром промежуточного программного обеспечения, она должна быть:

class TokenAuthMiddlewareInstance:
    def __init__(self, scope, middleware):
        self.middleware = middleware
        self.scope = dict(scope)
        self.inner = self.middleware.inner

    async def __call__(self, receive, send):
        close_old_connections()
        headers = dict(self.scope["headers"])
        print(headers[b"cookie"])
        if b"authorization" in headers[b"cookie"]:
            print('still good here')
            cookies = headers[b"cookie"].decode()
            token_key = re.search("authorization=(.*)(; )?", cookies).group(1)
            if token_key:
                self.scope["user"] = await get_user(token_key)

        inner = self.inner(self.scope)
        return await inner(receive, send) 


TokenAuthMiddlewareStack = lambda inner: TokenAuthMiddleware(AuthMiddlewareStack(inner))

спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...