mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-19 00:15:08 +00:00
Update api key header
Use more common X-Api-Key header with no prefix Also updates Unauthorized response to include a json error body and simplifies working with new API key via curl and the vscode rest client Signed-off-by: James Taylor <jamest@uk.ibm.com>
This commit is contained in:
parent
c3a34ef559
commit
05f7026e58
5 changed files with 145 additions and 98 deletions
26
README.md
26
README.md
|
|
@ -48,52 +48,60 @@ npm run start:dev
|
|||
|
||||
## REST API
|
||||
|
||||
If everything went well, you can now make basic asset transfer REST calls! For example...
|
||||
If everything went well, you can now make basic asset transfer REST calls!
|
||||
|
||||
The examples below require a `SAMPLE_APIKEY` environment variable which must be set to an API key from the `.env` file created above.
|
||||
|
||||
For example, to use the ORG1_APIKEY...
|
||||
|
||||
```
|
||||
SAMPLE_APIKEY=$(grep ORG1_APIKEY .env | cut -d '=' -f 2-)
|
||||
```
|
||||
|
||||
### Get all assets...
|
||||
|
||||
```shell
|
||||
curl http://localhost:3000/api/assets
|
||||
curl --header "X-Api-Key: ${SAMPLE_APIKEY}" http://localhost:3000/api/assets
|
||||
```
|
||||
|
||||
### Check whether an asset exists...
|
||||
|
||||
```shell
|
||||
curl --include --request OPTIONS http://localhost:3000/api/assets/asset7
|
||||
curl --include --header "X-Api-Key: ${SAMPLE_APIKEY}" --request OPTIONS http://localhost:3000/api/assets/asset7
|
||||
```
|
||||
|
||||
### Create an asset...
|
||||
|
||||
```shell
|
||||
curl --include --header "Content-Type: application/json" --header "api-key:Api-Key <apikeyfororg>" --request POST --data '{"id":"asset7","color":"red","size":42,"owner":"Jean","appraisedValue":101}' http://localhost:3000/api/assets
|
||||
curl --include --header "Content-Type: application/json" --header "X-Api-Key: ${SAMPLE_APIKEY}" --request POST --data '{"id":"asset7","color":"red","size":42,"owner":"Jean","appraisedValue":101}' http://localhost:3000/api/assets
|
||||
```
|
||||
|
||||
### Read transaction status...
|
||||
|
||||
```shell
|
||||
curl --header "api-key:Api-Key <apikeyfororg>" http://localhost:3000/api/transactions/__transaction_id__
|
||||
curl --header "X-Api-Key: ${SAMPLE_APIKEY}" http://localhost:3000/api/transactions/__transaction_id__
|
||||
```
|
||||
|
||||
### Read an asset...
|
||||
|
||||
```shell
|
||||
curl --header "api-key:Api-Key <apikeyfororg>" http://localhost:3000/api/assets/asset7
|
||||
curl --header "X-Api-Key: ${SAMPLE_APIKEY}" http://localhost:3000/api/assets/asset7
|
||||
```
|
||||
|
||||
### Update an asset...
|
||||
|
||||
```shell
|
||||
curl --include --header "Content-Type: application/json" --header "api-key:Api-Key <apikeyfororg>" --request PUT --data '{"id":"asset7","color":"red","size":11,"owner":"Jean","appraisedValue":101}' http://localhost:3000/api/assets/asset7
|
||||
curl --include --header "Content-Type: application/json" --header "X-Api-Key: ${SAMPLE_APIKEY}" --request PUT --data '{"id":"asset7","color":"red","size":11,"owner":"Jean","appraisedValue":101}' http://localhost:3000/api/assets/asset7
|
||||
```
|
||||
|
||||
### Transfer an asset...
|
||||
|
||||
```shell
|
||||
curl --include --header "Content-Type: application/json" --header "api-key:Api-Key <apikeyfororg>" --request PATCH --data '[{"op":"replace","path":"/owner","value":"Ashleigh"}]' http://localhost:3000/api/assets/asset7
|
||||
curl --include --header "Content-Type: application/json" --header "X-Api-Key: ${SAMPLE_APIKEY}" --request PATCH --data '[{"op":"replace","path":"/owner","value":"Ashleigh"}]' http://localhost:3000/api/assets/asset7
|
||||
```
|
||||
|
||||
### Delete an asset...
|
||||
|
||||
```shell
|
||||
curl --include --header "api-key:Api-Key <apikeyfororg>" --request DELETE http://localhost:3000/api/assets/asset7
|
||||
curl --include --header "X-Api-Key: ${SAMPLE_APIKEY}" --request DELETE http://localhost:3000/api/assets/asset7
|
||||
```
|
||||
|
|
|
|||
84
asset-transfer-basic/rest-api-typescript/demo.http
Normal file
84
asset-transfer-basic/rest-api-typescript/demo.http
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
// Demo file for use with REST Client for Visual Studio Code
|
||||
// See https://github.com/Huachao/vscode-restclient
|
||||
//
|
||||
// Edit the values below to match your environment if required
|
||||
@hostname = localhost
|
||||
@port = {{$dotenv PORT}}
|
||||
@baseUrl = http://{{hostname}}:{{port}}
|
||||
@apiUrl = {{baseUrl}}/api
|
||||
@api-key = {{$dotenv ORG1_APIKEY}}
|
||||
|
||||
### Check the server is ready
|
||||
|
||||
GET {{baseUrl}}/ready HTTP/1.1
|
||||
|
||||
### Check the server is still live
|
||||
|
||||
GET {{baseUrl}}/live HTTP/1.1
|
||||
|
||||
### Get all assets
|
||||
|
||||
GET {{apiUrl}}/assets HTTP/1.1
|
||||
X-Api-Key: {{api-key}}
|
||||
|
||||
### Check if asset exists
|
||||
|
||||
OPTIONS {{apiUrl}}/assets/asset7 HTTP/1.1
|
||||
X-Api-Key: {{api-key}}
|
||||
|
||||
### Create asset
|
||||
|
||||
POST {{apiUrl}}/assets HTTP/1.1
|
||||
content-type: application/json
|
||||
X-Api-Key: {{api-key}}
|
||||
|
||||
{
|
||||
"id": "asset7",
|
||||
"color": "red",
|
||||
"size": 42,
|
||||
"owner": "Jean",
|
||||
"appraisedValue": 101
|
||||
}
|
||||
|
||||
### Read transaction status
|
||||
|
||||
GET {{apiUrl}}/transactions/__transaction_id__ HTTP/1.1
|
||||
X-Api-Key: {{api-key}}
|
||||
|
||||
### Read asset
|
||||
|
||||
GET {{apiUrl}}/assets/asset7 HTTP/1.1
|
||||
X-Api-Key: {{api-key}}
|
||||
|
||||
### Update asset
|
||||
|
||||
PUT {{apiUrl}}/assets/asset7 HTTP/1.1
|
||||
content-type: application/json
|
||||
X-Api-Key: {{api-key}}
|
||||
|
||||
{
|
||||
"id": "asset7",
|
||||
"color": "red",
|
||||
"size": 11,
|
||||
"owner": "Jean",
|
||||
"appraisedValue": 101
|
||||
}
|
||||
|
||||
### Transfer asset
|
||||
|
||||
PATCH {{apiUrl}}/assets/asset7 HTTP/1.1
|
||||
content-type: application/json
|
||||
X-Api-Key: {{api-key}}
|
||||
|
||||
[
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/owner",
|
||||
"value": "Ashleigh"
|
||||
}
|
||||
]
|
||||
|
||||
### Delete asset
|
||||
|
||||
DELETE {{apiUrl}}/assets/asset7 HTTP/1.1
|
||||
X-Api-Key: {{api-key}}
|
||||
|
|
@ -1,24 +1,61 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { logger } from './logger';
|
||||
import passport from 'passport';
|
||||
import { NextFunction, Request, Response } from 'express';
|
||||
import { HeaderAPIKeyStrategy } from 'passport-headerapikey';
|
||||
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
|
||||
import * as config from './config';
|
||||
|
||||
const { UNAUTHORIZED } = StatusCodes;
|
||||
|
||||
export const fabricAPIKeyStrategy: HeaderAPIKeyStrategy =
|
||||
new HeaderAPIKeyStrategy(
|
||||
{ header: 'api-key', prefix: 'Api-Key ' },
|
||||
true,
|
||||
{ header: 'X-API-Key', prefix: '' },
|
||||
false,
|
||||
function (apikey, done) {
|
||||
logger.debug({ apikey }, 'Checking X-API-Key');
|
||||
const user: { org: string } = {
|
||||
org: '',
|
||||
};
|
||||
if (apikey === config.org1ApiKey) {
|
||||
user.org = 'Org1';
|
||||
logger.info('Organisation set to Org1');
|
||||
logger.debug('Organisation set to Org1');
|
||||
done(null, user);
|
||||
|
||||
//todo
|
||||
//add org2 apikey check
|
||||
} else {
|
||||
logger.debug('APIKEY Mismatch');
|
||||
logger.debug({ apikey }, 'No valid X-API-Key');
|
||||
return done(null, false);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export const authenticateApiKey = (
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): void => {
|
||||
passport.authenticate(
|
||||
'headerapikey',
|
||||
{ session: false },
|
||||
function (err, user, _info) {
|
||||
if (err) return next(err);
|
||||
if (!user)
|
||||
return res.status(UNAUTHORIZED).json({
|
||||
status: getReasonPhrase(UNAUTHORIZED),
|
||||
reason: 'NO_VALID_APIKEY',
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
req.logIn(user, { session: false }, (err) => {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
return next();
|
||||
});
|
||||
}
|
||||
)(req, res, next);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ const {
|
|||
SERVICE_UNAVAILABLE,
|
||||
} = StatusCodes;
|
||||
|
||||
import { fabricAPIKeyStrategy } from './auth';
|
||||
import { authenticateApiKey, fabricAPIKeyStrategy } from './auth';
|
||||
import passport from 'passport';
|
||||
export const createServer = async (): Promise<Application> => {
|
||||
const app = express();
|
||||
|
|
@ -98,16 +98,8 @@ export const createServer = async (): Promise<Application> => {
|
|||
throw new Error('Example error');
|
||||
});
|
||||
|
||||
app.use(
|
||||
'/api/assets',
|
||||
passport.authenticate('headerapikey', { session: false }),
|
||||
assetsRouter
|
||||
);
|
||||
app.use(
|
||||
'/api/transactions',
|
||||
passport.authenticate('headerapikey', { session: false }),
|
||||
transactionsRouter
|
||||
);
|
||||
app.use('/api/assets', authenticateApiKey, assetsRouter);
|
||||
app.use('/api/transactions', authenticateApiKey, transactionsRouter);
|
||||
|
||||
// For everything else
|
||||
app.use((_req, res) =>
|
||||
|
|
|
|||
74
demo.http
74
demo.http
|
|
@ -1,74 +0,0 @@
|
|||
// Demo file for use with REST Client for Visual Studio Code
|
||||
// See https://github.com/Huachao/vscode-restclient
|
||||
@hostname = localhost
|
||||
@port = 3000
|
||||
@baseUrl = http://{{hostname}}:{{port}}/api
|
||||
|
||||
//Get the apikey from .env file
|
||||
@api-key= Api-Key 295069C9-ABF5-4D2A-A020-2FF9F4E8DF07
|
||||
|
||||
### Get all assets
|
||||
GET {{baseUrl}}/assets HTTP/1.1
|
||||
api-key: {{api-key}}
|
||||
|
||||
### Check if asset exists
|
||||
|
||||
OPTIONS {{baseUrl}}/assets/asset7 HTTP/1.1
|
||||
api-key: {{api-key}}
|
||||
|
||||
### Create asset
|
||||
|
||||
POST {{baseUrl}}/assets HTTP/1.1
|
||||
content-type: application/json
|
||||
api-key: {{api-key}}
|
||||
|
||||
{
|
||||
"id": "asset7",
|
||||
"color": "red",
|
||||
"size": 42,
|
||||
"owner": "Jean",
|
||||
"appraisedValue": 101
|
||||
}
|
||||
|
||||
### Read transaction status
|
||||
|
||||
GET {{baseUrl}}/transactions/__transaction_id__ HTTP/1.1
|
||||
api-key: {{api-key}}
|
||||
|
||||
### Read asset
|
||||
|
||||
GET {{baseUrl}}/assets/asset7 HTTP/1.1
|
||||
api-key: {{api-key}}
|
||||
|
||||
### Update asset
|
||||
|
||||
PUT {{baseUrl}}/assets/asset7 HTTP/1.1
|
||||
content-type: application/json
|
||||
api-key: {{api-key}}
|
||||
|
||||
{
|
||||
"id": "asset7",
|
||||
"color": "red",
|
||||
"size": 11,
|
||||
"owner": "Jean",
|
||||
"appraisedValue": 101
|
||||
}
|
||||
|
||||
### Transfer asset
|
||||
|
||||
PATCH {{baseUrl}}/assets/asset7 HTTP/1.1
|
||||
content-type: application/json
|
||||
api-key: {{api-key}}
|
||||
|
||||
[
|
||||
{
|
||||
"op": "replace",
|
||||
"path": "/owner",
|
||||
"value": "Ashleigh"
|
||||
}
|
||||
]
|
||||
|
||||
### Delete asset
|
||||
|
||||
DELETE {{baseUrl}}/assets/asset7 HTTP/1.1
|
||||
api-key: {{api-key}}
|
||||
Loading…
Reference in a new issue