Git Product home page Git Product logo

socketio-jwt's People

Contributors

aaguiarz avatar alekseykulikov avatar allcontributors[bot] avatar annyv2 avatar ansien avatar aslafy-z avatar baoist avatar bartlomiej-korpus avatar chenkie avatar daedalus11069 avatar dbrugne avatar dependabot[bot] avatar gjsmith66 avatar jfromaniello avatar jghaines avatar kaisle avatar kerolloz avatar kjellski avatar konradsopala avatar mrforlorn avatar ntotten avatar otothea avatar pose avatar prmtl avatar rickheere avatar root-core avatar sayakmukhopadhyay avatar screeny05 avatar theoludwig avatar vmartynets avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

socketio-jwt's Issues

[Bug] Doesn't work with React 18

I've created new React 18 app using https://reactjs.org/docs/create-a-new-react-app.html
I've added the required packages and code from the readme but when I try to run the app I'm getting this error:

[ERROR in ./node_modules/buffer-equal-constant-time/index.js 4:13-37

Module not found: Error: Can't resolve 'buffer' in 'E:\React\socket-react\node_modules\buffer-equal-constant-time'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:

  • add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
  • install 'buffer'
    If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "buffer": false }

ERROR in ./node_modules/jwa/index.js 5:13-30

Module not found: Error: Can't resolve 'crypto' in 'E:\React\socket-react\node_modules\jwa'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:

  • add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
  • install 'crypto-browserify'
    If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "crypto": false }

ERROR in ./node_modules/jwa/index.js 9:11-26

Module not found: Error: Can't resolve 'util' in 'E:\React\socket-react\node_modules\jwa'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:

  • add a fallback 'resolve.fallback: { "util": require.resolve("util/") }'
  • install 'util'
    If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "util": false }

ERROR in ./node_modules/jws/lib/data-stream.js 4:13-30

Module not found: Error: Can't resolve 'stream' in 'E:\React\socket-react\node_modules\jws\lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:

  • add a fallback 'resolve.fallback: { "stream": require.resolve("stream-browserify") }'
  • install 'stream-browserify'
    If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "stream": false }

ERROR in ./node_modules/jws/lib/data-stream.js 6:11-26

Module not found: Error: Can't resolve 'util' in 'E:\React\socket-react\node_modules\jws\lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:

  • add a fallback 'resolve.fallback: { "util": require.resolve("util/") }'
  • install 'util'
    If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "util": false }

ERROR in ./node_modules/jws/lib/sign-stream.js 8:13-30

Module not found: Error: Can't resolve 'stream' in 'E:\React\socket-react\node_modules\jws\lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:

  • add a fallback 'resolve.fallback: { "stream": require.resolve("stream-browserify") }'
  • install 'stream-browserify'
    If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "stream": false }

ERROR in ./node_modules/jws/lib/sign-stream.js 12:11-26

Module not found: Error: Can't resolve 'util' in 'E:\React\socket-react\node_modules\jws\lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:

  • add a fallback 'resolve.fallback: { "util": require.resolve("util/") }'
  • install 'util'
    If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "util": false }

ERROR in ./node_modules/jws/lib/tostring.js 2:13-37

Module not found: Error: Can't resolve 'buffer' in 'E:\React\socket-react\node_modules\jws\lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:

  • add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
  • install 'buffer'
    If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "buffer": false }

ERROR in ./node_modules/jws/lib/verify-stream.js 8:13-30

Module not found: Error: Can't resolve 'stream' in 'E:\React\socket-react\node_modules\jws\lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:

  • add a fallback 'resolve.fallback: { "stream": require.resolve("stream-browserify") }'
  • install 'stream-browserify'
    If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "stream": false }

ERROR in ./node_modules/jws/lib/verify-stream.js 12:11-26

Module not found: Error: Can't resolve 'util' in 'E:\React\socket-react\node_modules\jws\lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:

  • add a fallback 'resolve.fallback: { "util": require.resolve("util/") }'
  • install 'util'
    If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "util": false }

ERROR in ./node_modules/safe-buffer/index.js 2:13-30

Module not found: Error: Can't resolve 'buffer' in 'E:\React\socket-react\node_modules\safe-buffer'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:

  • add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
  • install 'buffer'
    If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "buffer": false }

Steps To Reproduce

  1. clone my test repo: https://github.com/Misiu/react-socket-io-jwt
  2. Start the dev server
  3. See the errors

The current behavior

I'm getting errors

The expected behavior

No errors

Client side usage example has errors.

Documentation :

  • Is Missing
  • Is Confusing
  • Has Typo errors
  • Not Sure?

Proposal

Using [email protected], the example given for adding the Authorization header does not work.

This:

const socket = io('http://localhost:9000', {
  extraHeaders: { Authorization: `Bearer ${yourJWT}` }
})

Should be:

const socket = io('http://localhost:9000', {
            transportOptions: {
                polling: {
                    extraHeaders: {
                        Authorization: `Bearer ${yourJWT}`,
                    },
                },
            },
        });

Server-side authorize function does not work as advertised in README example

Steps To Reproduce

Using jwks-rsa version 1.12.2.

  1. Step 1
    Try to use the server-side example code from the README.

The current behavior

image
image

Also, if debugging key, it returns children kid, alg, nbf, publicKey and getPublicKey. No "rsaPublicKey".

decodedToken is weakly typed.

I managed to get the example to compile with the following code:

      secret: async (decodedToken) => {
        console.debug("I'm trying to authorize...", decodedToken)
        if (
          decodedToken &&
          typeof decodedToken === "object" &&
          "header" in decodedToken &&
          decodedToken.header.kid
        ) {
          const key = await client.getSigningKeyAsync(decodedToken.header.kid)
          return key.getPublicKey()
        }
        return ""
      },

However, the problem that remains is that io.on("connection" never fires and there is no sign that the connection is established at all.

The token and authentication in place is the same that already successfully works with my express-jwt middleware.

The expected behavior

The above does not happen.

jwks-RSA Support

Description

The addition of the support of jwks-RSA (https://www.npmjs.com/package/jwks-rsa)

Describe the solution you'd like

Support for this feature can be seen in the fork of ssnxd (https://www.npmjs.com/package/@ssnxd/socketio-jwt/v/4.5.3).
The original repo does not support this feature as far as I know.

Example of the implementation currently in use:

io.sockets
    .use(
        authorize({
            algorithms: ['RS256'],
            secret: jwksRsa.expressJwtSecret({
                cache: true,
                rateLimit: true,
                jwksRequestsPerMinute: 5,
                jwksUri: `https://${process.env.DOMAIN}/oauth2/jwks`
            }),
            timeout: 15000
        })
    )

[Feature] Add support for WebSocket as transport

Description

We can use socket.io with mutiple transports type, as it is described in the socket.io documentation : https://socket.io/docs/v3/client-initialization/#transports

Currently, we only support polling transport.
If you use the websocket transport, you can't pass the token in the extraHeaders : https://socket.io/docs/v3/client-initialization/#extraHeaders, so we don't support it.

Describe the solution you'd like

Maybe we could retrieve the token thanks to query string instead of the extraHeaders : https://socket.io/docs/v3/client-initialization/#query

Types for Connect Error

Apologies if this is poorly worded as I'm just getting started with Typescript.

I'm trying to implement types as instructed in the Socket.io documentation, and my IDE is throwing an error on the connect_error event for this package.

This bit:

this.socket.on('connect_error', (err) => {
      if (err.data && err.data.type === 'UnauthorizedError') {
        console.log('User token has expired');
      }
    });

Results in:
Property 'data' does not exist on type 'Error'.ts(2339)

Is there a best practice way of fixing this? Thanks.

[Feature] Addition of a configurable user property to the socket object

Description

Write now, the socket object has the encoded and decoded tokens as custom properties. One QoL improvement would be to have the user object too, much like how passport injects req.user

Describe the solution you'd like

The solution would be similar to passport wherein a new option can be added which takes in a function which is executed after the token is decoded and validated. The result of this function can then be added to the user property of the socket object.

Describe alternatives you've considered

The alternative would be to use the decodedToken to fetch the user object which is fine in itself but I think this feature would go a long way in making life easy.

I already have a PoC available and if you agree with this feature, I will raise a PR.

[Feature] Alternative to "auth" for requiring bearer token

Description

Currently, if you require a bearer token thusly in your server...

// Require Bearer Token
const socket = io('http://localhost:9000', {
  auth: { token: `Bearer ${yourJWT}` }
})

The only way you can be authorized is to connect with a client something like this...

        this.io = io(`${socketioAddress}`, <SocketIOClient.ConnectOpts>{
            perMessageDeflate: false,
            transports: ['websocket'],
            upgrade: false,
            auth: { token: `Bearer ${this.tSessionService.token}` }
        });

However, some web socket clients (like WebSocket4Net for C#) don't have support for this.

Describe the solution you'd like

Would it be possible to also support including the bearer token in a header as well? Something in authorize.js pehaps...

const authorize = (options) => {
    const { secret, algorithms = ['HS256'], onAuthentication } = options;
    return async (socket, next) => {
        let encodedToken = null;
        const { token } = socket.handshake.auth;
        const { authentication } = socket.handshake.headers;
        const authenticationToken = token || authentication;
        if (authenticationToken != null) {
            const tokenSplitted = authenticationToken.split(' ');
            if (tokenSplitted.length !== 2 || tokenSplitted[0] !== 'Bearer') {
                return next(new UnauthorizedError_1.UnauthorizedError('credentials_bad_format', {
                    message: 'Format is Authorization: Bearer [token]'
                }));

After Authorize events are not firing

Steps To Reproduce

  1. Server Side
this.io = new Server(this.di.server.listener);
this.io.use(
    authorize({
        secret: "test"
    })
);
this.io
    .on('connection', socket => {
        console.log("authenticated", socket.decodedToken); // No any messages in console
 });
  1. Client Side
io({
    extraHeaders: { Authorization: `Bearer ${Cookie.get('jwt')}}` }
});
    "socket.io": "^3.0.5",
    "socket.io-client": "^3.0.5"

The current behavior

No any actions happens after middleware of socket.io using this package.
I mean on.("connection") never fired after adding use(authorize(...). Once I'm removing use(authorize(...)) sockets are connects fine.

Add encoded and decoded token to socket type

Type of Improvement :

  • Files and Folders Structure
  • Performance
  • Refactoring code
  • Tests
  • Not Sure?

Proposal

Extend socket property type so its properties are visible for TypeScript.

  1. define new TS interface for socket e.g.
interface ExtendedSocket extends Socket {
   encodedToken?: string;
   decodedToken?: any;
}
  1. make property socket in SocketIOMiddleware of type ExtendedSocket
type SocketIOMiddleware = (
  socket: ExtendedSocket,
  next: (err?: ExtendedError) => void
) => void

Handle jwt expiration after a while

What I can see socketio-jwt makes sure the jwt is valid and has not expired during the connection phase. But if the token expires after a while, the token will still be considered valid and the user will be able to perform actions without having a valid token?

Is there any protection against that that I have missed?

No timeout option?

I am switching from socketio-jwt to @thream/socketio-jwt.
My original authorization options object include a timeout. I don't see anything about timeouts not being supported in the documentation despite this item being forked from socketio-jwt.

TS error:

Argument of type '{ secret: string; timeout: number; algorithms: "HS256"[]; }' is not assignable to parameter of type 'AuthorizeOptions'. Object literal may only specify known properties, and 'timeout' does not exist in type 'AuthorizeOptions'.ts(2345)

The current behavior

I cannot add a timeout option in the AuthorizeOptions

The expected behavior

I can include a timeout option in the AuthorizeOptions

I feel like this is a bug but if this should be feature request instead, feel free to change th label. Thanks!

[Feature] Bump jsonwebtoken to v9.0.0

Description

There is a security issue with jsonwebtoken library in v8.5.1

Describe the solution you'd like

This could be nice to bump jsonwebtoken to v9.0.0 where a fix have been made

[Question] How can I use this plugin with 'require'?

Question

Hey!

Can you help me please regarding using @thream/socketio-jwt with 'require'? Currently, I am getting error code: 'ERR_REQUIRE_ESM'. I can't use the module type (import) since my entire nodejs server is built with require.

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.