Skip to content

Commit 48cca5c

Browse files
Paulo Cabralwaldyrious
authored andcommitted
Add authentication sample using client credentials
1 parent 875ee48 commit 48cca5c

File tree

7 files changed

+221
-0
lines changed

7 files changed

+221
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Base Url endpoint
2+
BASE_URL='https://api-sandbox.uphold.com'
3+
4+
CLIENT_ID = ''
5+
CLIENT_SECRET = ''
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.env
2+
node_modules/
3+
package-lock.json
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Client credentials flow
2+
3+
This sample project demonstrates how to authenticate in the Uphold API using the client credentials flow. For further background, please refer to the [API documentation](https://uphold.com/en/developer/api/documentation).
4+
5+
## Summary
6+
7+
**Ideal for backend integrations** that do not require access to other Uphold user accounts.
8+
9+
This sample project performs the following actions:
10+
11+
- Get Token
12+
- List Assets
13+
14+
**Important notice:** In Uphold's production environment, client credentials authentication is only available for **business accounts**, and requires manual approval from Uphold.
15+
Please [contact Uphold](mailto:developer@uphold.com) to obtain this permission.
16+
For applications that use the sandbox environment, as is the case with this demo project, those requirements can be skipped.
17+
18+
## Requirements
19+
20+
- `node` v13.14.0 +
21+
22+
## Setup
23+
24+
- run `npm install` (or `yarn install`)
25+
- create a `.env` file based on the `.env.example` file, and populate it with the required data
26+
27+
## Run
28+
29+
- run `node index.js`
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/**
2+
* Dependencies.
3+
*/
4+
5+
import axios from "axios";
6+
import b64Pkg from "js-base64";
7+
import dotenv from "dotenv";
8+
import path from "path";
9+
import qs from "qs";
10+
const { encode } = b64Pkg;
11+
12+
/**
13+
* Dotenv configuration.
14+
*/
15+
dotenv.config({ path: path.resolve() + "/.env" });
16+
17+
/**
18+
* Get Token.
19+
*/
20+
export async function getToken() {
21+
// Base64-encoded authentication credentials
22+
const auth = encode(process.env.CLIENT_ID + ":" + process.env.CLIENT_SECRET);
23+
24+
// Options for the Axios request
25+
const options = {
26+
method: "POST",
27+
headers: {
28+
Authorization: "Basic " + auth,
29+
"content-type": "application/x-www-form-urlencoded",
30+
},
31+
data: qs.stringify({ grant_type: "client_credentials" }),
32+
url: `${process.env.BASE_URL}/oauth2/token`,
33+
};
34+
35+
const data = axios(options)
36+
.then((response) => {
37+
return response.data;
38+
})
39+
.catch((error) => {
40+
error.response.data.errors
41+
? console.log(JSON.stringify(error.response.data.errors, null, 2))
42+
: console.log(JSON.stringify(error, null, 2));
43+
throw error;
44+
});
45+
46+
return data;
47+
}
48+
49+
/**
50+
* Get assets.
51+
*/
52+
export async function getAssets(token) {
53+
try {
54+
const response = await axios.get(`${process.env.BASE_URL}/v0/assets`, {
55+
headers: {
56+
Authorization: `${token.token_type} ${token.access_token}`,
57+
},
58+
});
59+
return response.data;
60+
} catch (error) {
61+
console.log(JSON.stringify(error, null, 2));
62+
throw error;
63+
}
64+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Dependencies.
3+
*/
4+
5+
import { getAssets, getToken } from "./cc-flow.js";
6+
7+
(async () => {
8+
// Get `bearer` token from sandbox
9+
const token = await getToken();
10+
// Log the output of an API call using the token, to confirm that it works
11+
console.log(await getAssets(token));
12+
})();
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "uphold-ccf",
3+
"version": "0.0.1",
4+
"description": "Uphold Client Credential Flow Example",
5+
"license": "MIT",
6+
"main": "index.js",
7+
"type": "module",
8+
"dependencies": {
9+
"axios": "^0.20.0",
10+
"btoa": "^1.2.1",
11+
"dotenv": "^8.2.0",
12+
"js-base64": "^3.5.2",
13+
"qs": "^6.9.4",
14+
"require": "^2.4.20"
15+
},
16+
"engines": {
17+
"node": ">=13.14"
18+
},
19+
"scripts": {
20+
"run": "node index.js "
21+
}
22+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2+
# yarn lockfile v1
3+
4+
5+
amdefine@>=0.0.4:
6+
version "1.0.1"
7+
resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
8+
integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=
9+
10+
async@~0.2.6:
11+
version "0.2.10"
12+
resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1"
13+
integrity sha1-trvgsGdLnXGXCMo43owjfLUmw9E=
14+
15+
axios@^0.20.0:
16+
version "0.20.0"
17+
resolved "https://registry.yarnpkg.com/axios/-/axios-0.20.0.tgz#057ba30f04884694993a8cd07fa394cff11c50bd"
18+
integrity sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==
19+
dependencies:
20+
follow-redirects "^1.10.0"
21+
22+
btoa@^1.2.1:
23+
version "1.2.1"
24+
resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73"
25+
integrity sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==
26+
27+
dotenv@^8.2.0:
28+
version "8.2.0"
29+
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a"
30+
integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==
31+
32+
follow-redirects@^1.10.0:
33+
version "1.13.0"
34+
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db"
35+
integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==
36+
37+
js-base64@^3.5.2:
38+
version "3.5.2"
39+
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-3.5.2.tgz#3cc800e4f10812b55fb5ec53e7cabaef35dc6d3c"
40+
integrity sha512-VG2qfvV5rEQIVxq9UmAVyWIaOdZGt9M16BLu8vFkyWyhv709Hyg4nKUb5T+Ru+HmAr9RHdF+kQDKAhbJlcdKeQ==
41+
42+
optimist@~0.3.5:
43+
version "0.3.7"
44+
resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.3.7.tgz#c90941ad59e4273328923074d2cf2e7cbc6ec0d9"
45+
integrity sha1-yQlBrVnkJzMokjB00s8ufLxuwNk=
46+
dependencies:
47+
wordwrap "~0.0.2"
48+
49+
qs@^6.9.4:
50+
version "6.9.4"
51+
resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687"
52+
integrity sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==
53+
54+
require@^2.4.20:
55+
version "2.4.20"
56+
resolved "https://registry.yarnpkg.com/require/-/require-2.4.20.tgz#66cb6baaabb65de8a71d793f5c65fd184f3798b6"
57+
integrity sha1-Zstrqqu2XeinHXk/XGX9GE83mLY=
58+
dependencies:
59+
std "0.1.40"
60+
uglify-js "2.3.0"
61+
62+
source-map@~0.1.7:
63+
version "0.1.43"
64+
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346"
65+
integrity sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=
66+
dependencies:
67+
amdefine ">=0.0.4"
68+
69+
std@0.1.40:
70+
version "0.1.40"
71+
resolved "https://registry.yarnpkg.com/std/-/std-0.1.40.tgz#3678a5f65094d9e1b6b5e26edbfc0212b8342b71"
72+
integrity sha1-Nnil9lCU2eG2teJu2/wCErg0K3E=
73+
74+
uglify-js@2.3.0:
75+
version "2.3.0"
76+
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.3.0.tgz#2cdec16d378a8a2b6ecfb6989784cf8b7ae5491f"
77+
integrity sha1-LN7BbTeKiituz7aYl4TPi3rlSR8=
78+
dependencies:
79+
async "~0.2.6"
80+
optimist "~0.3.5"
81+
source-map "~0.1.7"
82+
83+
wordwrap@~0.0.2:
84+
version "0.0.3"
85+
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
86+
integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc=

0 commit comments

Comments
 (0)