JavaScript를 사용하여 기본 클라이언트에서 Magento API에 액세스하는 방법


9

로컬 JavaScript 기반 응용 프로그램 (Titanium Desktop)에서 Magento API에 액세스하여 가장 좋은 방법이 궁금합니다.

내가 지금까지 알아 낸 것 :

질문 :

  • 인증 메커니즘을 응용 프로그램 키 및 비밀을 사용하여 HMAC 기반 인증과 같은 것으로 교환 할 수 있습니까? 입증 된 솔루션이 있습니까?
  • 그렇지 않은 경우 Magento에서 OAuth 사용자 에이전트 흐름이 가능합니까? 설명서에는 언급되어 있지 않습니다.
  • 사용자로부터 대부분의 인증 프로세스를 숨기기 위해 AJAX (Cross-Origin-Policy는 여기서 문제가되지 않음)로 사용자 자격 증명을 제출할 수 있습니까? 그러면 액세스 토큰을 응답에서 직접 추출 할 수 있습니다.

OK, 나는 REST에 너무 집중했다는 것을 알았습니다 .JavaScript를 사용하는 SOAP는 번거롭지 만 SOAP API는 내 문제를 해결해야합니다. 티타늄 라이브러리 ( github.com/kwhinnery/Suds )가 있습니다. 시험 해보고 결과를 여기에 게시하겠습니다.
— Fabian Schmengler

답변:


8

편집 : 더 나은 방법을 찾았습니다. 아래 솔루션 2를 참조하십시오.

의견에서 언급했듯이 SOAP API는 갈 길입니다.

해결책 1 :

Suds 는 약간의 수정 (나를 Titanium.Network.HTTPClient대신 사용)으로 나를 위해 XMLHttpRequest일했지만 호출을위한 SOAP 봉투를 만들고 전체 XML 응답을 반환하는 것 이상은 아닙니다.

요청 체인에 jQuery Deferred 를 사용한 개념 증명 구현 :

Service.MagentoClient = function()
{
    var self = this;
    var suds = new SudsClient({
        endpoint : "http://the-magento-host/api/v2_soap/",
        targetNamespace : "urn:Magento",
    });

    self.login = function() {
        var deferred = new $.Deferred();
        var args = {
            username : 'the-username',
            apiKey: 'the-api-key'
        };
        suds.invoke("login", args, function(xmlDoc) {
            self.sessionId = $(xmlDoc).find("loginReturn").text();
            deferred.resolve({});
            //TODO reject if no sessionid returned
        });
        return deferred;
    };

    self.setStatus = function(orderId, status, comment, notify) {
        var deferred = new $.Deferred();
        if (!self.sessionId) {
            deferred.reject({ error: 'Login not successful.' });
            return;
        }
        var args = {
            sessionId        : self.sessionId,
            orderIncrementId : orderId,
            status           : status,
            comment          : comment,
            notify           : notify
        }
        suds.invoke("salesOrderAddComment", args, function(xmlDoc) {
            var success = $(xmlDoc).find("salesOrderAddCommentResponse").text();
            if (success) {
                deferred.resolve({});
            } else {
                deferred.reject({ error: 'Update not successful.' });
            }

        });
        return deferred;
    };
};

사용 예 :

        var magento = new Service.MagentoClient();
        magento.login().then(function() {
            magento.setStatus('100000029', 'complete', 'soap test');
        }).then(function() {
            alert('Update successful');
        }, function(reject) {
            alert('Update failed: ' + reject.error);
        });

해결책 2 :

자체 API 어댑터를 작성하는 것이 정말 쉽다는 것이 밝혀졌습니다. 예를 들어이 핵심 핵(데드 링크)에 기반한 JSON-RPC 어댑터에 대한 깨끗한 모듈을 작성할 수있었습니다 Zend_Json_Server. SOAP 및 XML-RPC API와 동일한 인증 및 ACL을 사용합니다.

진입 점을 사용하려면 /api/jsonrpc새 컨트롤러를 api경로에 추가해야 합니다.

<config>
    <frontend>
        <routers>
            <api>
                <args>
                    <modules>
                        <my_jsonrpc before="Mage_Api">My_JsonRpc_Api</my_jsonrpc>
                    </modules>
                </args>
            </api>
        </routers>
    </frontend>
</config>

2015 년 2 월 업데이트 : 위의 링크가 현재 종료되었으므로 JSON-RPC 어댑터를 완전한 확장으로 소스로 열었습니다 : https://github.com/sgh-it/jsonrpc

내 JS 클라이언트는 이제 다음과 같습니다 (JQuery.Deferred와 함께 추가되지만 API에 대한 추가 타사 라이브러리는 없습니다).

/**
 * Client for the Magento API
 */
Service.MagentoClient = function()
{
    var self = this;

    /**
     * @param string   method    the remote procedure to call
     * @param object   params    parameters for the RPC
     * @param callback onSuccess callback for successful request. Expects one parameter (decoded response object)
     * @param callback onError   callback for failed request. Expects one parameter (error message)
     * 
     * @return void
     */
    self.jsonRpc = function(method, params, onSuccess, onError) {
        var request = {
            method : method,
            params : params,
            jsonrpc : "2.0",
            id : 1
        };

        var options = {
            entryPoint : config.magentoClient.entryPoint,
            method: 'post',
            timeout: config.magentoClient.timeout
        };

        var httpClient = Titanium.Network.createHTTPClient();
        httpClient.onload = function(e) {
            try {
                var response = JSON.parse(this.responseText);
            } catch (jsonError) {
                return onError(jsonError);
            }
            if (response.error) {
                if (response.error.code == 5) { // session expired
                    self.sessionId = null;
                }
                return onError(response.error.message);
            }
            onSuccess(response);
        };
        httpClient.onerror = function(e) {
            onError(e.error + '; Response:' + this.responseText);
        };
        httpClient.setTimeout(options.timeout);

        if (httpClient.open(options.method, options.entryPoint)) {
            httpClient.setRequestHeader("Content-type", "application/json");
            httpClient.send(JSON.stringify(request));
        } else {
            onError('cannot open connection');
        }

    }
    /**
     * Retrieve session id for API
     * 
     * @return JQuery.Deferred deferred object for asynchronous chaining
     */
    self.login = function() {
        var deferred = new $.Deferred();
        if (self.sessionId) {
            deferred.resolve();
            return deferred;
        }
        var loginParams = config.magentoClient.login;
        try {
            self.jsonRpc('login', loginParams, function(response) {
                if (response && response.result) {
                    self.sessionId = response.result;
                    deferred.resolve();
                } else {
                    deferred.reject('Login failed.');
                }
            }, function(error) {
                deferred.reject(error);
            });
        } catch (rpcError) {
            deferred.reject(rpcError);
        }
        return deferred;
    };
    /**
     * Updates order states in Magento
     *
     * @param string method   name of the remote method
     * @param object args     arguments for the remote method
     * 
     * @return JQuery.Deferred deferred object for asynchronous chaining
     */
    self.call = function(method, args) {
        var deferred = new $.Deferred();
        if (!self.sessionId) {
            deferred.reject('No session.');
            return;
        }
        var callParams = {
            sessionId : self.sessionId,
            apiPath   : method,
            args      : args
        };
        try {
            self.jsonRpc('call', callParams, function(response) {
                deferred.resolve(response.result);
            }, function(error) {
                deferred.reject(error);
            });
        } catch (rpcError) {
            deferred.reject(rpcError);
        }

        return deferred;
    };
};

로그인 후 모든 메소드는를 통해 라우팅됩니다 call. method파라미터 등 무언가 sales_order.list1, args파라미터에있어서의 인수 배열 또는 개체.

사용 예 :

        var filters = [];
        var magento = new Service.MagentoClient();
        magento.login().then(function() {
            magento.call('sales_order.list', [filters]).then(
                function(orders) {
                    // do something with the response
                }, function(error) {
                    alert('Magento API error: ' + error);
                }
            );
        });

스크립트에서 엔드 포인트를 구성하는 방법은 무엇입니까?
— Akrramo

프론트 엔드 라우터 정의를 다음과 같이 변경 config.xml해야 api합니다 (라우트 를 사용하지 않으려면 대신 커스텀 라우트를 사용할 수 있습니다. 다른 Magento 모듈에서와 같이 정의하십시오)
— Fabian Schmengler

이 코드를 magento에 넣을 수있는 곳
— er.irfankhan11

설치 지침이 있습니다 github.com/sgh-it/jsonrpc
— 파비안 Schmengler

그리고 JavaScript 코드는 분명히 Magento가 아니라 외부 클라이언트에 속합니다
— Fabian Schmengler
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.