首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >oauth-1.0a节点包返回401用于Zotero (NodeJS)

oauth-1.0a节点包返回401用于Zotero (NodeJS)
EN

Stack Overflow用户
提问于 2018-12-19 21:31:48
回答 1查看 213关注 0票数 0

我使用oauth-1.0a节点包来使用Zotero实现OAuth。

我正在使用在zotero-oauth-示例回购中找到的代码。

运行上面提到的回购中的代码是有效的。我认为我的实现不起作用,因为我已经将回购中的单个函数划分为两个函数->示例repo不处理重定向客户端和处理回调。

我认为问题是:--我认为实例化两个不同的OAuth对象(一个是步骤1,另一个在步骤3)正在破坏一些东西。注意,我暂时保留了步骤1的hash_function中产生的散列,这是在步骤3中使用的。

我对OAuth不熟悉。你对我该尝试什么有什么建议吗?

1)请求令牌(服务器)

代码语言:javascript
复制
// omitting includes packages
const tokenRequestConfig = {
        url: 'https://www.zotero.org/oauth/request',
        method: 'POST',
        data: {
           

 oauth_callback: baseURL, // redirect to baseURL
            },
        },

        initZoteroIntegration = async () => {
            let oAuthHash;

            const oauth = OAuth({
                    consumer: {
                        key: process.env.ZOTERO_APP_CLIENT_KEY,
                        secret: process.env.ZOTERO_APP_CLIENT_SECRET,
                    },
                    signature_method: 'HMAC-SHA1',
                    hash_function(base_string, key) {
                        oAuthHash = crypto.createHmac('sha1', key).update(base_string).digest('base64');
                        return oAuthHash;
                    },
                }),

                tokenRequestResponse = await fetch('https://www.zotero.org/oauth/request', {
                    headers: oauth.toHeader(oauth.authorize(tokenRequestConfig)),
                    method: 'post',
                }),

                tokenRequestData = await tokenRequestResponse.text(),
                obj = {};

            tokenRequestData.replace(/([^=&]+)=([^&]*)/g, (m, key, value) => {
                obj[decodeURIComponent(key)] = decodeURIComponent(value);
            });

            const oAuthToken = obj.oauth_token,
                oAuthTokenSecret = obj.oauth_token_secret,
                url = `https://www.zotero.org/oauth/authorize?oauth_token=${oAuthToken}&library_access=1&notes_access=1&write_access=1&all_groups=write`;

            /* the url should be returned to the client */
            return ({
                url,
                oAuthToken,
                oAuthTokenSecret,
                oAuthHash,
            });
        };

2)客户端被定向到Zotero应用程序登录并授权权限。

3)令牌交换(服务器)

代码语言:javascript
复制
// omitting includes packages
const confirmIntegration = async ({oAuthToken, oAuthTokenSecret, oAuthVerifier, oAuthHash}) => {
            const oauth = OAuth({
                    consumer: {
                        key: process.env.ZOTERO_APP_CLIENT_KEY,
                        secret: process.env.ZOTERO_APP_CLIENT_SECRET,
                    },
                    signature_method: 'HMAC-SHA1',
                    hash_function() {
                        return oAuthHash;
                    },
                }),

                tokenExchangeConfig = {
                    url: `https://www.zotero.org/oauth/access?oauth_token=${oAuthToken}`,
                    method: 'POST',
                    data: {
                        oauth_verifier: oAuthVerifier,
                        oauth_callback: baseURL,
                    },
                },

                tokenExchangeResponse = await fetch(`https://www.zotero.org/oauth/access?oauth_token=${oAuthToken}`, {
                    headers: oauth.toHeader(oauth.authorize(tokenExchangeConfig, {
                        public: oAuthToken,
                        secret: oAuthTokenSecret,
                    })),
                    method: 'post',
                }),

                tokenExchangeData = await tokenExchangeResponse.text();

            try {
                const username = tokenExchangeData.match(/username=(\w+)/)[1],
                    userID = tokenExchangeData.match(/userID=([0-9]+)/)[1],
                    userAPIKey = tokenExchangeData.match(/oauth_token_secret=([a-zA-Z0-9]+)/)[1];


            return {
                    username,
                    userID,
                    userAPIKey,
                };
            } catch (e) {
                // TODO throw some error
                return null;
            }
        };

在‘令牌交换’步骤上,我得到一个带有401状态代码(“未经授权”)的响应。

tokenExchangeResponse.text()正在返回oauth_problem=signature_invalid

这是原始输出:

代码语言:javascript
复制
"https_sig_error=1&z_debug_sbs=POST&https%3A%2F%2Fwww.zotero.org%2Foauth%2Faccess&oauth_consumer_key%3D9a016199db19772cb220%26oauth_nonce%3DDs3iXBVWF4izl1qfX0mk0JXIvZkl7N5o%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1545238813%26oauth_token%3D6f6ade01f30625feeb36%26oauth_verifier%3D02469ed77305b02befd8%26oauth_version%3D1.0&oauth_problem=signature_invalid&debug_sbs=POST&https%3A%2F%2Fwww.zotero.org%2Foauth%2Faccess&oauth_consumer_key%3D9a016199db19772cb220%26oauth_nonce%3DDs3iXBVWF4izl1qfX0mk0JXIvZkl7N5o%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1545238813%26oauth_token%3D6f6ade01f30625feeb36%26oauth_verifier%3D02469ed77305b02befd8%26oauth_version%3D1.0"

*Fix Ok,我找到了一个解决方案。我使用node-cache在有限的时间内缓存OAuth对象。

感谢您@tnajdek澄清了OAuth的上述用法是问题所在。

EN

回答 1

Stack Overflow用户

发布于 2018-12-19 22:36:20

注意,我暂时保留了步骤1的hash_function中产生的散列,这是在步骤3中使用的。

这不管用。

hash_function构造函数的OAuth参数采用base_string (它是请求的序列化摘要)和key来生成其结果。base_stringkey在步骤1和步骤3之间都不同,但是hash_function返回步骤1中缓存的结果,作为步骤3中完全不同的参数base_stringkey的结果。

我不知道您的应用程序的其余部分是什么样子,但是我只创建一次OAuth实例,并在初始请求中和服务器请求处理例程中的回调请求中重用它。如果这不是一个选项,您可以使用相同的参数重新创建OAuth,并且它应该工作得很好。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53859439

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档