Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Magento OAuth Authentication can not handle custom URL scheme

To get the an OAuth token back I want to use a custom URL scheme as a callback URL for my iOS app, e.g. myapp://oauth-callback.

However it seems like Magento can not handle such a URL scheme as it returns with the following error message

HTTP Status 400: Bad Request, Response: oauth_problem=parameter_rejected&message=oauth_callback

If I set a callback URL beginning with http:// the request does work and I get back an OAuth token, the problem is that the OS opens the browser with this URL and this is an unwanted behaviour in our app.

like image 491
gpichler Avatar asked Dec 14 '25 17:12

gpichler


1 Answers

Your url is not valid in Zend_Uri::check($url) because of 'myapp'. Here is check() function:

public static function check($uri)
{
    try {
        $uri = self::factory($uri);
    } catch (Exception $e) {
        return false;
    }

    return $uri->valid();
}

Let's look how the factory work:

public static function factory($uri = 'http', $className = null)
    {
        // Separate the scheme from the scheme-specific parts
        $uri            = explode(':', $uri, 2);
        $scheme         = strtolower($uri[0]);
        $schemeSpecific = isset($uri[1]) === true ? $uri[1] : '';

        if (strlen($scheme) === 0) {
            #require_once 'Zend/Uri/Exception.php';
            throw new Zend_Uri_Exception('An empty string was supplied for the scheme');
        }

        // Security check: $scheme is used to load a class file, so only alphanumerics are allowed.
        if (ctype_alnum($scheme) === false) {
            #require_once 'Zend/Uri/Exception.php';
            throw new Zend_Uri_Exception('Illegal scheme supplied, only alphanumeric characters are permitted');
        }

        if ($className === null) {
            /**
             * Create a new Zend_Uri object for the $uri. If a subclass of Zend_Uri exists for the
             * scheme, return an instance of that class. Otherwise, a Zend_Uri_Exception is thrown.
             */
            switch ($scheme) {
                case 'http':
                    // Break intentionally omitted
                case 'https':
                    $className = 'Zend_Uri_Http';
                    break;

                case 'mailto':
                    // TODO
                default:
                    #require_once 'Zend/Uri/Exception.php';
                    throw new Zend_Uri_Exception("Scheme \"$scheme\" is not supported");
                    break;
            }
        }

        #require_once 'Zend/Loader.php';
        try {
            Zend_Loader::loadClass($className);
        } catch (Exception $e) {
            #require_once 'Zend/Uri/Exception.php';
            throw new Zend_Uri_Exception("\"$className\" not found");
        }

        $schemeHandler = new $className($scheme, $schemeSpecific);

        if (! $schemeHandler instanceof Zend_Uri) {
            #require_once 'Zend/Uri/Exception.php';
            throw new Zend_Uri_Exception("\"$className\" is not an instance of Zend_Uri");
        }

        return $schemeHandler;
    }

It use Zend_Uri_Http class for http:// and https:// schemes. You just need to add own scheme in list.

How to fix?

  1. Copy lib/Zend/Uri.php file to app/code/local/Zend/Uri.php
  2. In factory function found 'switch' code block (~line 119) and replace it with next: switch ($scheme) { case 'http': // Break intentionally omitted case 'https': $className = 'Zend_Uri_Http'; break; case 'myapp': $className = 'Zend_Uri_Http'; break; case 'mailto': // TODO default: #require_once 'Zend/Uri/Exception.php'; throw new Zend_Uri_Exception("Scheme \"$scheme\" is not supported"); break; }
  3. Save file and clear Magento cache. Now your myapp:// scheme will work as http:// and https://
like image 97
ToxaBes Avatar answered Dec 16 '25 07:12

ToxaBes



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!