1

I'm attempting to build an app for the students at my school using the schoology API, and when trying to get a request token, I get the "OAuth Verification Failed: Verification of signature failed" error. I'm using express to access the API, my code is as follows:

function getToken(key, secret){


    var token;
    var parameters = {
        Authorization: 'OAuth',
        realm: 'Schoology API',
        oauth_consumer_key: key,
        oauth_nonce: nonce(20),
        oauth_timestamp: Math.floor(Date.now()/1000),
        oauth_signature_method: 'HMAC-SHA1',
        oauth_version: '1.0',

    }
    function generateBaseString(httpMethod, url, parameters){
        var encodeURL = encodeURIComponent(url);

        var paramList = [];
        var paramString = '';
        console.log("Unencoded key: " + parameters['oauth_consumer_key']);
        console.log("Encoded key: " + encodeURIComponent(parameters['oauth_consumer_key']));
        for(var k in parameters) {
            console.log(k + ' Added to base string: ' + encodeURIComponent(k) + "=" + encodeURIComponent(parameters[k]));
            paramList.push(encodeURIComponent(k) + "=" + encodeURIComponent(parameters[k]));
        }
        paramString = encodeURIComponent(paramList.sort().join('&'));

        return httpMethod + '&' + encodeURL + '&' + paramString;
    }


    base_string = generateBaseString('GET', 'https://api.schoology.com/v1/oauth/request_token', parameters);
    oauth_string = secret + '&';

    var signature = (new Buffer(hmacsha1(oauth_string, base_string))).toString('base64');
    console.log("Signature is " + signature);
    console.log("Base string is " + base_string);
    console.log("Oauth string is " + oauth_string);
    var header = {
        Authorization: 'OAuth',
        realm: parameters.realm,
        oauth_consumer_key: parameters.oauth_consumer_key,
        oauth_nonce: parameters.oauth_nonce,
        oauth_signature_method: parameters.oauth_signature_method,
        oauth_timestamp: parameters.oauth_timestamp,
        oauth_version: parameters.oauth_version,
        oauth_signature: signature,
        oauth_callback: 'oob'
    }


    var options = {
        hostname: 'api.schoology.com',
        port: 443,
        path: '/v1/oauth/request_token',
        method: 'GET',
        header: header,
    }

    var url =   'https://api.schoology.com/v1/oauth/request_token?' + 
                'Authorization=OAuth' +
                'realm=' + parameters.realm +
                '&oauth_consumer_key=' + parameters.oauth_consumer_key + 
                '&oauth_nonce=' + parameters.oauth_nonce +
                '&oauth_signature_method=' + parameters.oauth_signature_method +
                '&oauth_timestamp=' + parameters.oauth_timestamp +
                '&oauth_version=' + parameters.oauth_version +
                '&oauth_signature=' + signature +
                '&oauth_callback=' + 'oob'
    ;
    console.log("URL: " + url);
    // return
    var req = https.request(url, (res) => {
        console.log('statusCode:', res.statusCode);
        console.log('headers:', res.headers);

        let data = '';
        res.on('data', (d) => {
            console.log("DATA");
            data += d;
        });

        res.on('end', () => {
            token = JSON.parse(data);
        });
    });

    req.on('error', (e => {
        console.error("Error: " + e.message);
    }));

    req.end();


    return token;
}

The response header contains a 401 error. Using POST returns a 405 error. Any ideas?

1 Answers1

2

I just got oath working with Schoology -- you have a couple of options:

  1. Since the request is sent HTTPS (secure) they will accept a PLAINTEXT signature method with a simpler <consumer-secret>&<token-secret> signature.

  2. If you want to use the HMAC signature method, the parameters you are sending do not look quite like what they are using for the baseString. If you examine the response body you get with 401, you can see what their server used as the base string and compare that to yours.

I doubt that sending the Authorization as url params will work. You need to build one string to send as the "Authorization" header that looks about like this:

OAuth realm="Schoology API",oauth_consumer_key="(your consumer key)",oauth_token="",oauth_nonce="(some random string)",oauth_timestamp="1599876905",oauth_signature_method="PLAINTEXT",oauth_version="1.0",oauth_signature="(your consumer secret)%26"
Joe Beuckman
  • 2,264
  • 2
  • 24
  • 63