chore: initial commit

This commit is contained in:
divlo
2020-12-27 17:25:44 +01:00
parent 04294c69c5
commit 2e5d281f46
27 changed files with 813 additions and 740 deletions

218
README.md
View File

@@ -1,9 +1,9 @@
# socketio-jwt
[![All Contributors](https://img.shields.io/badge/all_contributors-5-orange.svg?style=flat-square)](#contributors)
<img src="https://img.shields.io/badge/community-driven-brightgreen.svg"/> <br>
<img src="https://img.shields.io/badge/community-driven-brightgreen.svg"/> <br>
### Contributors
## Contributors
Thanks goes to these wonderful people who contribute(d) or maintain(ed) this repo ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
@@ -38,14 +38,17 @@ npm install socketio-jwt
```javascript
// set authorization for socket.io
io.sockets
.on('connection', socketioJwt.authorize({
secret: 'your secret or public key',
timeout: 15000 // 15 seconds to send the authentication message
}))
.on(
'connection',
socketioJwt.authorize({
secret: 'your secret or public key',
timeout: 15000 // 15 seconds to send the authentication message
})
)
.on('authenticated', (socket) => {
//this socket is authenticated, we are good to handle more events from it.
console.log(`hello! ${socket.decoded_token.name}`);
});
console.log(`hello! ${socket.decoded_token.name}`)
})
```
**Note:** If you are using a base64-encoded secret (e.g. your Auth0 secret key), you need to convert it to a Buffer: `Buffer('your secret key', 'base64')`
@@ -53,7 +56,7 @@ io.sockets
**Client side**
```javascript
const socket = io.connect('http://localhost:9000');
const socket = io.connect('http://localhost:9000')
socket.on('connect', () => {
socket
.emit('authenticate', { token: jwt }) //send the jwt
@@ -61,10 +64,10 @@ socket.on('connect', () => {
//do other things
})
.on('unauthorized', (msg) => {
console.log(`unauthorized: ${JSON.stringify(msg.data)}`);
throw new Error(msg.data.type);
console.log(`unauthorized: ${JSON.stringify(msg.data)}`)
throw new Error(msg.data.type)
})
});
})
```
### One roundtrip
@@ -72,34 +75,39 @@ socket.on('connect', () => {
The previous approach uses a second roundtrip to send the jwt. There is a way you can authenticate on the handshake by sending the JWT as a query string, the caveat is that intermediary HTTP servers can log the url.
```javascript
const io = require('socket.io')(server);
const socketioJwt = require('socketio-jwt');
const io = require('socket.io')(server)
const socketioJwt = require('socketio-jwt')
```
With socket.io < 1.0:
```javascript
io.set('authorization', socketioJwt.authorize({
secret: 'your secret or public key',
handshake: true
}));
io.set(
'authorization',
socketioJwt.authorize({
secret: 'your secret or public key',
handshake: true
})
)
io.on('connection', (socket) => {
console.log('hello!', socket.handshake.decoded_token.name);
});
console.log('hello!', socket.handshake.decoded_token.name)
})
```
With socket.io >= 1.0:
```javascript
io.use(socketioJwt.authorize({
secret: 'your secret or public key',
handshake: true
}));
io.use(
socketioJwt.authorize({
secret: 'your secret or public key',
handshake: true
})
)
io.on('connection', (socket) => {
console.log('hello!', socket.decoded_token.name);
});
console.log('hello!', socket.decoded_token.name)
})
```
For more validation options see [auth0/jsonwebtoken](https://github.com/auth0/node-jsonwebtoken).
@@ -111,7 +119,7 @@ Append the jwt token using query string:
```javascript
const socket = io.connect('http://localhost:9000', {
query: `token=${your_jwt}`
});
})
```
Append the jwt token using 'Authorization Header' (Bearer Token):
@@ -119,7 +127,7 @@ Append the jwt token using 'Authorization Header' (Bearer Token):
```javascript
const socket = io.connect('http://localhost:9000', {
extraHeaders: { Authorization: `Bearer ${your_jwt}` }
});
})
```
Both options can be combined or used optionally.
@@ -131,11 +139,13 @@ Require Bearer Tokens to be passed in as an Authorization Header
**Server side**:
```javascript
io.use(socketioJwt.authorize({
secret: 'your secret or public key',
handshake: true,
auth_header_required: true
}));
io.use(
socketioJwt.authorize({
secret: 'your secret or public key',
handshake: true,
auth_header_required: true
})
)
```
### Handling token expiration
@@ -145,7 +155,7 @@ io.use(socketioJwt.authorize({
When you sign the token with an expiration time (example: 60 minutes):
```javascript
const token = jwt.sign(user_profile, jwt_secret, { expiresIn: 60*60 });
const token = jwt.sign(user_profile, jwt_secret, { expiresIn: 60 * 60 })
```
Your client-side code should handle it as below:
@@ -154,11 +164,14 @@ Your client-side code should handle it as below:
```javascript
socket.on('unauthorized', (error) => {
if (error.data.type == 'UnauthorizedError' || error.data.code == 'invalid_token') {
if (
error.data.type == 'UnauthorizedError' ||
error.data.code == 'invalid_token'
) {
// redirect user to login page perhaps?
console.log('User token has expired');
console.log('User token has expired')
}
});
})
```
### Handling invalid token
@@ -175,12 +188,15 @@ Add a callback client-side to execute socket disconnect server-side.
```javascript
socket.on('unauthorized', (error, callback) => {
if (error.data.type == 'UnauthorizedError' || error.data.code == 'invalid_token') {
if (
error.data.type == 'UnauthorizedError' ||
error.data.code == 'invalid_token'
) {
// redirect user to login page perhaps or execute callback:
callback();
console.log('User token has expired');
callback()
console.log('User token has expired')
}
});
})
```
**Server side**
@@ -188,11 +204,14 @@ socket.on('unauthorized', (error, callback) => {
To disconnect socket server-side without client-side callback:
```javascript
io.sockets.on('connection', socketioJwt.authorize({
secret: 'secret goes here',
// No client-side callback, terminate connection server-side
callback: false
}))
io.sockets.on(
'connection',
socketioJwt.authorize({
secret: 'secret goes here',
// No client-side callback, terminate connection server-side
callback: false
})
)
```
**Client side**
@@ -204,11 +223,14 @@ Nothing needs to be changed client-side if callback is false.
To disconnect socket server-side while giving client-side 15 seconds to execute callback:
```javascript
io.sockets.on('connection', socketioJwt.authorize({
secret: 'secret goes here',
// Delay server-side socket disconnect to wait for client-side callback
callback: 15000
}))
io.sockets.on(
'connection',
socketioJwt.authorize({
secret: 'secret goes here',
// Delay server-side socket disconnect to wait for client-side callback
callback: 15000
})
)
```
Your client-side code should handle it as below:
@@ -217,12 +239,15 @@ Your client-side code should handle it as below:
```javascript
socket.on('unauthorized', (error, callback) => {
if (error.data.type == 'UnauthorizedError' || error.data.code == 'invalid_token') {
if (
error.data.type == 'UnauthorizedError' ||
error.data.code == 'invalid_token'
) {
// redirect user to login page perhaps or execute callback:
callback();
console.log('User token has expired');
callback()
console.log('User token has expired')
}
});
})
```
### Getting the secret dynamically
@@ -236,19 +261,21 @@ the provided token.
```javascript
const SECRETS = {
'user1': 'secret 1',
'user2': 'secret 2'
user1: 'secret 1',
user2: 'secret 2'
}
io.use(socketioJwt.authorize({
secret: (request, decodedToken, callback) => {
// SECRETS[decodedToken.userId] will be used as a secret or
// public key for connection user.
io.use(
socketioJwt.authorize({
secret: (request, decodedToken, callback) => {
// SECRETS[decodedToken.userId] will be used as a secret or
// public key for connection user.
callback(null, SECRETS[decodedToken.userId]);
},
handshake: false
}));
callback(null, SECRETS[decodedToken.userId])
},
handshake: false
})
)
```
### Altering the value of the decoded token
@@ -256,22 +283,20 @@ io.use(socketioJwt.authorize({
You can pass a function to change the value of the decoded token
```javascript
io.on(
'connection',
socketIOJwt.authorize({
customDecoded: (decoded) => {
return "new decoded token";
return 'new decoded token'
},
secret: 'my_secret_key',
decodedPropertyName: 'my_decoded_token',
}),
);
decodedPropertyName: 'my_decoded_token'
})
)
io.on('authenticated', (socket) => {
console.log(socket.my_decoded_token); // new decoded token
});
console.log(socket.my_decoded_token) // new decoded token
})
```
## Contribute
@@ -281,6 +306,7 @@ Feel like contributing to this repo? We're glad to hear that! Before you start c
Here you can also find the [PR template](https://github.com/auth0-community/socketio-jwt/blob/master/PULL_REQUEST_TEMPLATE.md) to fill once creating a PR. It will automatically appear once you open a pull request.
You might run the unit tests, before creating a PR:
```bash
npm test
```
@@ -307,31 +333,33 @@ This project is licensed under the MIT license. See the [LICENSE](https://github
Auth0 helps you to:
* Add authentication with [multiple authentication sources](https://docs.auth0.com/identityproviders), either social like
* Google
* Facebook
* Microsoft
* Linkedin
* GitHub
* Twitter
* Box
* Salesforce
* etc.
- Add authentication with [multiple authentication sources](https://docs.auth0.com/identityproviders), either social like
- Google
- Facebook
- Microsoft
- Linkedin
- GitHub
- Twitter
- Box
- Salesforce
- etc.
**or** enterprise identity systems like:
* Windows Azure AD
* Google Apps
* Active Directory
* ADFS
* Any SAML Identity Provider
* Add authentication through more traditional [username/password databases](https://docs.auth0.com/mysql-connection-tutorial)
* Add support for [linking different user accounts](https://docs.auth0.com/link-accounts) with the same user
* Support for generating signed [JSON Web Tokens](https://docs.auth0.com/jwt) to call your APIs and create user identity flow securely
* Analytics of how, when and where users are logging in
* Pull data from other sources and add it to user profile, through [JavaScript rules](https://docs.auth0.com/rules)
- Windows Azure AD
- Google Apps
- Active Directory
- ADFS
- Any SAML Identity Provider
- Add authentication through more traditional [username/password databases](https://docs.auth0.com/mysql-connection-tutorial)
- Add support for [linking different user accounts](https://docs.auth0.com/link-accounts) with the same user
- Support for generating signed [JSON Web Tokens](https://docs.auth0.com/jwt) to call your APIs and create user identity flow securely
- Analytics of how, when and where users are logging in
- Pull data from other sources and add it to user profile, through [JavaScript rules](https://docs.auth0.com/rules)
## Create a free Auth0 account
* Go to [Auth0 website](https://auth0.com/signup)
* Hit the **SIGN UP** button in the upper-right corner
- Go to [Auth0 website](https://auth0.com/signup)
- Hit the **SIGN UP** button in the upper-right corner