// Handle a request to a resource and authenticate the access token
   $token_OK = $server->verifyResourceRequest(OAuth2\Request::createFromGlobals());
   if (!$token_OK) {
-    $server->getResponse()->send();
+    $response = $server->getResponse();
+    if (!count($response->getParameters())) {
+      // We get an empty response if we don't get any auth header. Let's actually note that explicitly.
+      $response->setError($response->getStatusCode(), 'auth_missing', 'Authentication missing');
+    }
+    $response->send();
     if ($settings['piwik_enabled']) { $piwikTracker->doTrackPageView('API Request: Bad Token'); }
     exit();
   }
 
     // Add the "Refresh Token" grant type (required to get longer-living resource access by generating new access tokens)
     $server->addGrantType(new OAuth2\GrantType\RefreshToken($oauth2_storage, array('always_issue_new_refresh_token' => true)));
 
+    // Add 'token' response type (mirroring what getDefaultResponseTypes is doing).
+    $server->addResponseType(new OAuth2\ResponseType\AccessToken($oauth2_storage, $oauth2_storage, $oauth2_config));
+
+    // Add 'code' response type (mirroring what getDefaultResponseTypes is doing).
+    $server->addResponseType(new OAuth2\ResponseType\AuthorizationCode($oauth2_storage));
+
     return $server;
   }
 
     $table->addColumn('logged_in', 'boolean', array('notnull' => true, 'default' => false));
     $table->addColumn('time_created', 'datetime', array('notnull' => true, 'default' => 'CURRENT_TIMESTAMP'));
     $table->addColumn('time_expire', 'datetime', array('notnull' => true, 'default' => 'CURRENT_TIMESTAMP'));
-    $table->addColumn('saved_redirect', 'string', array('length' => 255, 'notnull' => true, 'default' => ''));
+    $table->addColumn('saved_redirect', 'string', array('length' => 2000, 'notnull' => true, 'default' => ''));
     $table->setPrimaryKey(array('id'), 'id');
     $table->addIndex(array('sesskey'), 'sesskey');
     $table->addIndex(array('time_expire'), 'time_expire');