Summary
I've authored several posts on the usage of the NiceIncontact (NiC) APIs, but never covered the authentication steps. This post will show how to do that for both the legacy and new Userhub configuration interfaces. I'll show a Typescript implementation of the necessary API calls for both API interfaces.API Access Keys
Legacy Interface
Below is a screenshot of the legacy admin interface of the 3 pieces of information necessary to generate an API bearer token.Userhub Interface
The newer Userhub interface requires the two pieces of info below to generate the API bearer token. This access key has been deleted, so there's no security concern here.API Authentication Class Design
Below is a diagram depicting the Typescript classes that will be used for generating API bearer tokens for the two access types mentioned above.Code
Authenticator Interface
export interface Authenticator { getToken():Promise<string>; };
Legacy Nic OAuth Class (getToken function)
async getToken():Promise<string> { let body; const username = this.credentials ? this.credentials.username : ''; const password = this.credentials ? this.credentials.password: ''; switch (this.grant) { case GRANT.CLIENT : { body = { 'grant_type' : 'client_credentials' }; break; }; case GRANT.PASSWORD : { body = { 'grant_type' : 'password', 'username' : username, 'password' : password } break; }; default : { throw new Error('unknown grant type'); } }; const response = await fetch(this.tokenURL, { method: 'POST', headers: { 'Content-Type' : 'application/json', 'Authorization' : 'basic ' + this.key }, body: JSON.stringify(body) }); if (response.ok) { const json = await response.json(); return json.access_token; } else { throw new Error(`response status: ${response.status} ${response.statusText}`); } }
Userhub Access Key Class (getToken function)
async getToken():Promise<string> { const body:object = { accessKeyId: this.key, accessKeySecret: this.secret } const response = await fetch(this.url, { method: 'POST', headers: { 'Content-Type' : 'application/json' }, body: JSON.stringify(body) }); if (response.ok) { const json = await response.json(); return json.access_token; } else { throw new Error(`getToken() response status: ${response.status} ${response.statusText}`); } }
Demo
async function demo():Promise { dotenv.config(); const app:any = process.env.NIC_APP; const vendor:any = process.env.NIC_VENDOR; const secret:any = process.env.NIC_SECRET; const username:any = process.env.NIC_USERNAME; const password:any = process.env.NIC_PASSWORD; const accessSecret:any = process.env.NIC_ACCESS_SECRET; const accessKey:any = process.env.NIC_ACCESS_KEY; let url:string = 'https://api.incontact.com/InContactAuthorizationServer/Token'; const clientAuth = new NicOAuth(app, vendor, secret, GRANT.CLIENT, url); let token:string = await clientAuth.getToken(); console.log(`client auth token: ${token}`); console.log(''); const credentials = new Credentials(username, password); const passwordAuth = new NicOAuth(app, vendor, secret, GRANT.PASSWORD, url, credentials); token = await passwordAuth.getToken(); console.log(`password auth token: ${token}`); console.log(''); url = 'https://na1.nice-incontact.com/authentication/v1/token/access-key'; const nicAccess = new NicAccess(accessKey, accessSecret, url); token = await nicAccess.getToken(); console.log(`access token: ${token}`); }
Results
$ npm run start > authdemo@1.0.0 start nicapiauth > node authdemo.js client auth token: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpY0JVSWQiOjQ1OTM0NDMsIm5hbWUiOiIiLCJpc3... password auth token: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpY0JVSWQiOjQ1OTM... access token: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.ey...
Source
https://github.com/joeywhelan/NiCAuthenticationCopyright ©1993-2024 Joey E Whelan, All rights reserved.