This library aims to ease the process of handling Did-Auth
process between different parts, its implemented according to ABT-DID-Protocol, and can eliminate the threat of middle-man attach if properly used, there are typically 2 use case for the library:
-
dApp <--> dApp
: for inter application communication, we provideAppAuthenticator
andAppHandlers
-
dApp <--> DID Wallet
: for application and wallet communication, we provideWalletAuthenticator
andWalletHandlers
npm install @arcblock/jwt
// or
yarn add @arcblock/jwt
WalletAuthenticator
and WalletHandlers
should be used together with @ocap/react-forge.
const { fromRandom } = require('@ocap/wallet');
const { WalletAuthenticator, WalletHandlers } = require('@arcblock/jwt');
// First setup authenticator and handler factory
const wallet = fromRandom().toJSON();
const authenticator = new WalletAuthenticator({
wallet,
baseUrl: 'http://wangshijun.natapp1.cc',
appInfo: {
description: 'Starter projects to develop web application on forge',
icon: '/images/logo@2x.png',
name: 'Forge Web Starter',
},
chainInfo: {
host: 'http://did-workshop.arcblock.co:8210/api',
id: 'forge',
},
});
const handlers = new WalletHandlers({
authenticator,
tokenStorage: new MongoStorage({ url: process.env.MONGO_URI }),
});
// Then attach handler to express server
const express = require('express');
const app = express();
// This is required if you want to use dynamic baseUrl inference
app.set('trust proxy', true);
handlers.attach({
prefix: '/api/did',
action: 'login',
claims: {
profile: () => ({
fields: ['fullName', 'email'],
description: 'Please provide your name and email to continue',
}),
},
onAuth: async ({ claims, userDid }) => {
try {
const profile = claims.find((x) => x.type === 'profile');
console.info('login.success', { userDid, profile });
} catch (err) {
console.error('login.error', err);
}
},
});
// Then your app will have 5 api endpoints that can be consumed by AuthComponent
// - `GET /api/did/login/token` create new token
// - `GET /api/did/login/status` check for token status
// - `GET /api/did/login/timeout` expire a token
// - `GET /api/did/login/auth` create auth response
// - `POST /api/did/login/auth` process login request
Please note that AppAuthenticator
and AppHandlers
should be used to sign and verify the message sent between dApps, so there must are both a client and a server.
const { fromRandom } = require('@ocap/wallet');
const { AppAuthenticator, AppHandlers } = require('@arcblock/jwt');
// First setup authenticator and handler factory
const wallet = fromRandom().toJSON();
const authenticator = new AppAuthenticator(wallet);
const handlers = new AppHandlers(authenticator);
const express = require('express');
const app = express();
app.post('/api/endpoint', handlers.attach(), (req, res) => {
console.log('client.appPk', req.appPk);
console.log('verified payload', req.payload);
// Sent signed response: sensitive info should not be here
res.jsonSecure({
key: 'value',
});
});
const axios = require('axios');
const signedPayload = authenticator.sign({
amount,
depositorDid,
depositorPk,
withdrawer: appAuth.wallet.address,
merchantId: process.env.MERCHANT_ID,
});
const res = await axios.post('http://example.com/api/endpoint', signedPayload);
const payload = await authenticator.verify(res.data);
if (payload.error) {
throw new Error(payload.error);
}
// Do something with the payload