Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to get context for subscriptions #1553

Closed
deathg0d opened this issue Aug 20, 2018 · 5 comments
Closed

Unable to get context for subscriptions #1553

deathg0d opened this issue Aug 20, 2018 · 5 comments

Comments

@deathg0d
Copy link

deathg0d commented Aug 20, 2018

I have the following code:

const server = new ApolloServer({
    ........

    subscriptions: {
        onConnect: (connectionParams, webSocket, context) => {
            // check for headers
            let username = <username from connectionParams->headers>
            return { username }   // according to the documentation, returning here adds the parameter to context, can't seem to get this in subscription function
        },
    },

    context: ({ req, res }) => {
        if (req, req.headers){
            // non-subscription calls
            return <username from connectionParams->headers>
        }else{
            // we get here when we use subscription query
            // req and res are empty
            return;
        }
    },

    ........
)}

And then in the subscription resolver

........

    Subscription: {
        somethingChanged: {
            // Additional event labels can be passed to asyncIterator creation
            subscribe: withFilter(() => pubsub.asyncIterator('SOMETHING_CHANGED'), (payload, variables, context, info) => {
                console.log(payload, variables, context, info)
                return true
            }),
        },
    },
........

I cannot seem to send the username from onConnect to the context within withFilter. I am trying to achieve this because once I have the context (i.e. headers/auth), I want to compare it to the payload.

@sbrichardson
Copy link
Contributor

please review this and see if it is a duplicate: #1526 (comment)

@deathg0d
Copy link
Author

deathg0d commented Aug 21, 2018

@sbrichardson @martijnwalraven I am not sure, may be there's another way for my specific use case. What I want to achieve is using header tokens verify that the user has permissions for a certain room, or another use case to deliver private chat message between two users.

Subscription can have variables that I can compare with payload like mentioned in examples but how can I verify that the user has permission to these variables. That is if a user subscribes using ... somethingChanged(room: some_room_id){ ... }, how do I verify that the user has enough permissions to access this room? onConnect does not seem to have access to these variables.

@deathg0d
Copy link
Author

deathg0d commented Sep 2, 2018

So, at the moment I found a hacky way to solve this. I could not find any other way to solve this yet. Also, this solution works only because I am using jwt token based api's. I currently have the following inside the withfilter:

........

    Subscription: {
        somethingChanged: {
            // Additional event labels can be passed to asyncIterator creation
            subscribe: withFilter(() => pubsub.asyncIterator('SOMETHING_CHANGED'), (payload, variables, context, info) => {
                if (variables has token field and the token is a valid jwt && jwt->username === payload.username){
                    return true
                }else{
                    return false
                }
            }),
        },
    },
........

And to subscribe, we need to do:

subscription{
    somethingChanged(token: <This token is the same token sent as auth header token>){
        id
    }
}

So basically, jwt in header is used to allow or deny from the onConnect function, and jwt token in subscription query is used to authenticate the current payload.

This is definitely a hacky way. Right from the start I can already see that it is a slight annoyance to send token in header as well as the query. But a bigger issue is that, when many users are subscribed to this 'SOMETHING_CHANGED' subscription, and if one user gets a notification, jwt is checked over all subscribed users. This I am guessing may affect performance.

@deathg0d
Copy link
Author

deathg0d commented Sep 30, 2018

Solved by #1597 (comment)

@thilllon
Copy link

@judithkoh

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 19, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants