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

Added Express.js Based Example for Signing HTTP responses #54

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 99 additions & 1 deletion docs/7-auth_service/5-jws-java-example.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,102 @@ public static void parseSignature(String detachedSignature, byte[] payload, RsaJ
throw exception;
}
}
```
```

# Node.js based Example for verifying signatures

```
const { JWS, JWK } = require('jose');
const { Writable } = require('stream');

class ReactiveResponseSigner {
constructor(response, key) {
this.response = response;
this.key = key;
}

// Method to sign the payload before sending the response
writeWith(payloadStream, detached = true) {
const buffers = [];

// Collect the payload data from the stream
payloadStream.on('data', (chunk) => {
buffers.push(chunk);
});

// Once all data is collected, sign the payload and send the response
payloadStream.on('end', async () => {
try {
const payload = Buffer.concat(buffers);
const signature = await this.sign(payload, detached);

// Set the signature in the response headers
this.response.setHeader('Signature', signature);

// Write the original payload to the response
this.response.write(payload);
this.response.end();
} catch (error) {
console.error('Error signing response:', error);
this.response.statusCode = 500;
this.response.end('Internal Server Error');
}
});
}

// Method to sign the payload
async sign(payload, detached) {
// Create the JWS signer with the payload
const signer = new JWS.Sign(payload);

// Set the algorithm and key to be used for signing
signer.recipient(this.key, { alg: 'RS256', b64: !detached });

// If detached, return the detached JWS; otherwise, return the full JWS
if (detached) {
return signer.sign('compact', { detached: true });
} else {
return signer.sign('compact');
}
}
}

module.exports = ReactiveResponseSigner;

```

Usage Example in Express.js

```
const express = require('express');
const { JWK } = require('jose');
const ReactiveResponseSigner = require('./ReactiveResponseSigner');

const app = express();

// JSON Web Key (JWK)
const jwk = JWK.generateSync('RSA', 2048, { alg: 'RS256', use: 'sig' });

app.use((req, res, next) => {

const signer = new ReactiveResponseSigner(res, jwk);

// Mock payload stream
const payloadStream = new Writable({
write(chunk, encoding, callback) {
callback(); // No-op, this is a mock stream
}
});

// Simulate the end of the payload with some content
payloadStream.end(Buffer.from(JSON.stringify({ message: "Hello, World!" })));

// Use the signer's writeWith method to sign and send the response
signer.writeWith(payloadStream);
});

app.listen(3000, () => {
console.log('Server is running on port 3000');
});

```