sessionConfig.perform未被调用

时间:2018-12-20 14:28:44

标签: zapier

我正在尝试为我的应用程序编写会话身份验证机制,就像这样:

import { ZObject, Bundle } from "zapier-platform-core";
import IAuthenticationScheme from "../interfaces/authentication/IAuthenticationScheme";

const getSessionKey = (z: ZObject, bundle: Bundle) => {
    console.log('GET SESSION called');
    const { username: auth_login, password: auth_password } = bundle.authData;
    return z.request({
        method: 'POST',
        url: 'http://******/perl/auth/login',
        body: { auth_login, auth_password }
    }).then(response => {
        z.console.log(response);
        console.log(response);

        if (response.status === 401) {
            throw new Error('The username/password you supplied is invalid');
        } else {
            return {
                sessionKey: z.JSON.parse(response.content).session_id
            };
        }
    });
};

const includeSessionKeyHeader = (request: any, z: ZObject, bundle: Bundle) => {
    console.log('includeSessionKeyHeader called');

    if (bundle.authData.sessionKey) {
        request.headers = Object.assign({}, request.headers);
        let { Cookie: cookie = '' } = request.headers;
        cookie = `${bundle.authData.sessionKey};${cookie}`;
        request.headers['Cookie'] = cookie;
    }
    return request;
};

const sessionRefreshIf401 = (response: any, z: ZObject, bundle: Bundle) => {
    console.warn('sessionRefreshIf401 called');
    if (bundle.authData.sessionKey) {
        if (response.status === 401) {
            throw new z.errors.RefreshAuthError(); // ask for a refresh & retry
        }
    }
    return response;
};

const test = (z: ZObject, bundle: Bundle) => {
    console.log('test called');
    return z.request({
        url: 'http://******/ruby/features'
    }).then((response) => {
        z.console.log(response);
        if (response.status === 401) {
            throw new Error('The API Key you supplied is invalid');
        }
        return response
    });
};

const authentication: IAuthenticationScheme<any> = {
    type: 'session',
    test,
    fields: [
        {
            key: 'username',
            type: 'string',
            required: true,
            helpText: 'Your login username.'
        },
        {
            key: 'password',
            type: 'string',
            required: true,
            helpText: 'Your login password.'
        }
    ],
    connectionLabel: (z, bundle) => {
        return bundle.inputData.username;
    },
    sessionConfig: {
        perform: getSessionKey
    }
};

export default {
    authentication,
    beforeRequest: { includeSessionKeyHeader },
    afterRequest: { sessionRefreshIf401 }
};

如您所见,我在每个函数的开头都放置了console.log标记,这样我就可以看到它们按什么顺序被调用。

这是我的测试配置:

import { should } from "should";
import { describe } from "mocha";
const { version } = require("../../package.json");
import { version as platformVersion } from "zapier-platform-core";
import { createAppTester } from "zapier-platform-core";
import PlackSession from "../authentication/PlackSession";

const App = {
    version,
    platformVersion,
    authentication: PlackSession.authentication,
    beforeRequest: [PlackSession.beforeRequest.includeSessionKeyHeader],
    afterResponse: [PlackSession.afterRequest.sessionRefreshIf401],
};

const appTester = createAppTester(App);

export default () => {
    describe('PlackSession authentication', () => {
        it('should authenticate', done => {
            console.log(`AUTHENTICATE!!`)
            const bundle = {
                authData: {
                    username: 'dev@******.com',
                    password: 'abc123'
                }
            };

            appTester(App.authentication.test, bundle)
                .then(response => {
                    console.log('BBBBBBBB')
                    done();
                })
                .catch(a => {
                    console.log('CCCCCC');
                    done(a)
                });

        });
    });
};

我可以按以下顺序查看测试输出的日志:

  authentication
    PlackSession authentication
AUTHENTICATE!!
test called
includeSessionKeyHeader called
CCCCCC
      1) should authenticate

这意味着永远不会调用sessionConfig.performgetSessionKey),这是应该通过login API调用交换凭据以进行身份​​验证的地方,我也可以在服务器中看到记录它永远不会被调用,它会直接跳到test调用并失败。

1 个答案:

答案 0 :(得分:0)

Zapier Platform团队的David在这里。好问题!

我认为问题在于您的测试。应该有两个功能。一个人应该呼叫App.authentication.sessionConfig.perform并测试将用户名和密码交换为令牌。另一个应该调用App.authentication.test,它测试使用有效密钥来获取受保护的资源。尽管它们可以链接在一起,但是也可以分别编写。

这里有一个更完整的示例:https://github.com/zapier/zapier-platform-example-app-session-auth/blob/cc63ca67cbc8933439577b2362d026ba2a701e36/test/basic.js