OAuth验证失败:签名验证失败(Schoology API)

时间:2020-01-09 18:01:13

标签: node.js express oauth-1.0a

我正在尝试使用学派API为学校的学生构建应用程序,并且在尝试获取请求令牌时,出现“ OAuth验证失败:签名验证失败”错误。我正在使用express访问API,我的代码如下:

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;
}

响应头包含401错误。使用POST会返回405错误。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我刚刚宣誓要与Schoology合作-您有两种选择:

  1. 由于请求是通过HTTPS(安全)发送的,因此他们将接受带有更简单的<consumer-secret>&<token-secret>签名的PLAINTEXT签名方法。

  2. 如果要使用HMAC签名方法,则发送的参数看起来与baseString所使用的参数不太相似。如果检查使用401获得的响应正文,则可以查看其服务器用作基本字符串并将其与您的服务器进行比较。

我怀疑将Authorization作为url参数发送会起作用。您需要构建一个字符串作为“ Authorization”标头发送,如下所示:

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"