关于node.js 验证 Oauth1.0 接口


下面的node.js调用Oauth接口并不是针对 腾讯开放平台.....具体不同的服务商可能在 oauth 基础上添砖加瓦,还要考虑具体的业务需求.


相比Oauth2.0来说,Oauth1.0真的很繁琐......

但是实际应用中碰到这个问题只能去解决,而不可能给对方打电话说,你赶紧把Oauth协议升级到2.0吧,1.0太繁琐,你想想将会发生什么事情 $#(+)&*@!! 


常常涉及到三方:

Service Provider:服务提供者(如 腾讯,只是假设)

Consumer:消费⽅,外部第三⽅方平台(如 一介布衣

User:用户 (登录用户)

当然我的博客不是多用户博客,只是举例.


前提条件:

在服务提供者平台申请到 appkey 和 secret


应用场景:

登录入口在服务方 (腾讯某个页面加入放置了 一介布衣 登录入口) 点击后页面在腾讯服务器打开,登陆后跳转到一介布衣,一介布衣得到需要的参数然后实现免登陆.

登录入口在第三方 (一介布衣 博客有个按钮,使用QQ帐号登录) 点击后页面跳转到腾讯服务器打开登陆窗口,登陆后再跳转到一介布衣某个地址,获取参数然后实现免登陆.


Oauth1.0调用流程:

1.一介布衣首先请求临时token 

2.腾讯返回临时未授权token request_token 给一介布衣

3.一介布衣带上 request_token 去请求授权token authorize_token

4.腾讯返回授权token  authorize_token

5.一介布衣带上 authorize_token 去请求具有访问权限的token  access_token

6.得到 access_token 后你就有权去调用授权的所有api了


上面的流程真的是痛苦,无助,绝望中......


上面一共需要来回获取3个token ,知道第三个才是有权有效的token,而真正在第一个token拿到手以后,后面的请求都类似.所以集中把获取 request_token 说一下.


OAuth 请求都需要使⽤用 HMAC-SHA1 算法来⽣生成签名.参数需要urlencode ,sign值需要escape .


比如请求url和参数是这样的:

oauth.qq.com/oauth/request_token?a=1&b=2&c=3&d=4&e=****

上面的最后一个参数e 需要把http请求方式(get/post) + 请求地址 + 参数a=1&b=2&c=3&d=4 求 HMAC-SHA1加密后的base64字符串.


实际应用中参数繁琐的很.

需要的必填参数:

oauth_consumer_key (就是appkey)

oauth_nonce (要求无重复字符串可以用时间戳来代替)

oauth_signature_method (加密方法 固定值 HMAC-SHA1)

oauth_timestamp  (9位时间戳 此值放在 oauth_signature_method 后面 )

oauth_version  (oauth 版本 固定值 1.0)


见代码:

var request=require('request');
var crypto = require('crypto');
var urlencode = require('urlencode');
var querystring = require('querystring');

function request_token(req_url,appkey,secret,callback) {
    var oauth_nonce = new Date().getTime();
    var parameters={
        oauth_consumer_key:appkey,
        oauth_nonce:oauth_nonce,
        oauth_signature_method:"HMAC-SHA1",
        oauth_timestamp:Math.round(oauth_nonce/1000),
        oauth_version:"1.0"
    };
    
    var kvdatas = [];
    _.each(_.keys(parameters).sort(), function(key) { //注意,这里要对参数进行排序
        kvdatas.push(key + '=' + parameters[key]);
    });

    var query_string = kvdatas.join('&');
    var bash_string = urlencode('GET') + '&' + urlencode(req_url) + '&' + urlencode(query_string);
    var oauth_signature = querystring.escape(crypto.createHmac('sha1', secret + '&').update(bash_string).digest('base64'));
    
    request.get(req_url+'?'+query_string+'&oauth_signature='+oauth_signature, function (error, response, body) {
        if(body){
            var rtnObj=querystring.parse(body);  //将a=b&c=d 的参数串格式化成object
            if(rtnObj){
                callback(null,rtnObj);
            }
            callback(null,null);
        }
    });
}

上面封装成一个公用的获取 request_token方法,你能看到所有参数需要 urlencode  , oauth_signature 需要 escape ,因为base64有类似 =号,传输后无法识别.


下面看调用:

    var request_token_url='http://oauth.qq.com/oauth/authorize_token';
    
    var appkey='你的 app_key';
    var app_secret='你的 app_secret';
    request_token(request_token_url,appkey,app_secret,function(err,retObject){
        console.log('----------',retObject);
        //上面打印出了retObject ,接着请求第二,第三次,最后拿到有权访问api的 access_token
    });


回到顶部