1

My goal is to consume an API which has already been deployed with nopCommerce (I do not have dev access to the server - I am just a user). There is a sample client application here, but the code is in C#. I have a webapp deployed on an Azure server using node.js. The API uses the OAuth 2.0 Authorization Code grant type.

I did a bit of Googling and it appears that client_credentials is typically used for this type of server to server flow:
How does 2-legged oauth work in OAuth 2.0?

Using OAuth for server-to-server authentication?

There is also an answer here which suggests that I can manually retrieve a token and then store it on the server. This is what I'm currently doing while testing my code.

I also found this answer which appears to be asking the same question. Like the author of that post, I am able to get a token via Postman, but my node.js code fails.

OAuth2.0 for nopCommerce

I wrote a minimal example in node.js here.

import { config } from 'dotenv';
import * as path from 'path';
import fetch from 'cross-fetch';

const ENV_FILE = path.join(__dirname, '.env');
const loadFromEnv = config({ path: ENV_FILE });

export async function getCodeUrl() {
    const params = {
        client_id: <CLIENT_ID>,
        redirect_uri: 'http://example.com',
        response_type: 'code',
    };
    console.log(params);

    const url = new URL(`http://example.com/OAuth/Authorize`);
    Object.keys(params).forEach(( key ) => url.searchParams.append(key, params[key]));
    const res = await fetch(url.href, { method: 'GET' });
    return res;
}

export async function getToken(code: string) {
    const url = new URL(`http://example.com/api/token`);
    const options = {
        form: {
            client_id: <CLIENT_ID>,
            client_secret: <CLIENT_SECRET>,
            code,
            grant_type: 'authorization_code',
            redirect_ui: 'http://example.com',
        },
        headers: { 'content-type': 'application/x-www-form-urlencoded' },
        method: 'POST',
    };

    console.log(options);
    const res = await fetch(url.href, options);
    console.log('res', res);
    return res;
}

const test = async () => {
    const codeUrlString = (await getCodeUrl()).url;
    const code = (new URL(codeUrlString).searchParams.get('code'));
    if (code) {
        console.log('code', code);
        const tokenResponse = await getToken(code);
        console.log('token res', tokenResponse);
    }
};

test();

I am successfully able to retrieve the authorization code, but when I use that in a POST request to get a token, I get this error:

{ error: 'invalid_client' }
MindSwipe
  • 7,193
  • 24
  • 47
zarak
  • 2,933
  • 3
  • 23
  • 29
  • It seems you checked out the 2 legged oauth in `Oauth 2.0` then why are you not using it as its basically for the case like yours(server-server communication without user interference) ? – Prakash Thete Jul 02 '19 at 06:10
  • @PrakashThete The server doesn't appear to have 2 legged auth enabled. I don't have access to the server to change the auth scheme. – zarak Jul 02 '19 at 09:01

0 Answers0