Challenges/Improvements & one bug - Wappler OAuth2 Connector

We wanted to integrate with KeyCloak which is an awesome IAM solution. OAuth2 is the way to go, just like how we are taken to facebook login page, I had to go to KeyCloak login page, complete the OAuth OIDC Auth Code Flow, and on successful login, redirect to my product page.

I had a lot of challenges implementing the Using OAuth2 Connector with Facebook guide successfully, but managed to figure out things over the last 10 days… Here is a quick summary of my feedback, and hacks. I know I’m not suppose to edit core files, but hopefully the wappler team @patrick @George can take the below feedback and improvise the oauth2 oob connector.

1. Debugging the server action file: The server-side debug flag sends additional details to the client-side regarding exceptions. But, in this flow, we are not calling the server-side api, rather completely navigating and opening the server-action file (under dmxConnect folder)… When things didn’t work, it was almost impossible to figure out what the issue was, as the page goes blank when hitting an error. I wish there was some wappler smarts there to debug & find our way. I ended up var_dump’ing from the oauth2.php core file to figure things out!

2. Redirect URI: This was a complete bummer for me. Looks like the redirect URI is constructed in getRedirectUri() which constructs it with various $_SERVER parameters. Most importantly, it missed setting the https for me, so SSL was constantly failing on me. I’m not sure if this is a smart way, as these server parameters are not always set depending on how our back-end is. What I ended up doing here is adding the below at the end of getRedirectUri() to override the auto-generated redirect URI with the correct redirect URL as a parameter (https://mydomain/dmxConnect/api/security/login_kc_auth_code.php):

image

       if(isset(((array)$this->options->params)['redirect_uri'])){
        $url = ((array)$this->options->params)['redirect_uri'];
    }

3. POST fields: Long story short, my keycloak auth endpoint expected the POST data as “application/x-www-form-urlencoded”, while wappler kept generated “multipart/form-data”… After a lot of time spent on stackoverflow, this link helped, I enclosed the $data within http_build_query to make it work for me. This possibly might have broken my pre-existing facebook direct oauth login (unused, so I didn’t test it).

    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));

4. BUG: I didn’t quite understand the difference between token handling (self-maintain vs session), but after completing the auth flow, and with a token in hand, I wanted to do a API get to fetch login user’s details such as name, etc… In my API call (api_acc below) I chose OAuth2 as Authorization field, and chose provider1 and this kept failing over and again.

After a lot of struggle I figured out that the token is actually in the Authorizer and not in the Provider. Wappler is incorrectly listing the provider while it should actually list the Authorizer for me to choose. I had to open the file, manually changed provider1 to my authorizer and the authorization token worked beautifully… This needs to be fixed.

In api.php,

    if ($options->oauth) {
        $oauth2 = $this->app->scope->get($options->oauth);
        if ($oauth2 && $oauth2->access_token) {
            $headers['Authorization'] = 'Bearer ' . $oauth2->access_token;
        }
    }

If it was suppose to the provider to use the tokens, then the tokens should be picked from the session variables.
image

Could this be why I’m unable to get Xero working here: OAuth2 to connect to Xero API ?

The easiest way to see the difference is try setting a value and open the data picker, in my case, it shows what’s returned in Provider & Authorizer steps.

image
So in the api call, when I choose Authorization as “OAuth2”, the dropdown displays only the provider (circle-1). In this dropdown, ideally I would have expected the Authorizer to be displayed as it’s the Authorizer that really has the access_toke & refresh_token.

Until this bug is fixed, I’m sending the access_token manually in the header (text in yellow circle-2). The inconvenience is I have to create unnecessary session variables if I had to use the access_token & refresh_token in other server actions.