Reputation: 6709
I am having trouble finding a method for authenticating API users in my application. I set out to initially build a system that users could access and authenticate through the web, but requirements have changed and I need to implement some additional actions that can be available in a RESTful manner using a POST API call.
I have created a class that extends CBehaviour
and forced a redirect to the login page for all unauthenticated users (found on the yii framework forum here). Problem is that all API calls are forced through the same logic and any POST requests simply spit out the HTML to the login page.
class ApplicationBehavior extends CBehavior {
private $_owner;
public function events() {
return array(
'onBeginRequest' => 'forceGuestLogin',
);
}
public function forceGuestLogin() {
$owner = $this->getOwner();
if ($owner->user->getIsGuest())
$owner->catchAllRequest = array("site/login");
}
}
How would I go about separating the authentication of API users from the Web users?
Upvotes: 3
Views: 5118
Reputation: 695
I would follow this guide on creating a REST API in Yii. After modifying the config urlManager entries, all of your API requests will use the APIController. You can then place the following code in the beforeAction of your APIController to return nothing if the user is a guest (Or an error message)
protected function beforeAction($event) {
if (Yii::app()->user->isGuest) {
echo "Invalid credentials";
Yii::app()->end();
}
}
Note: The code above works for my purposes because all REST requests are sent via the same browser. (Which is already logged in and has a login cookie)
If you replace that behavior with a new base controller placed in protected/controllers
to force login, it will only apply to your pages that require a login and not your APIController. Here is an example of mine:
//Make sure all Controllers which require a login inherit from this
class ControllerLoginRequired extends CController {
public function runAction($action) {
if (Yii::app()->user->isGuest && 'site' != $this->route) {
Yii::app()->user->returnUrl = $this->route;
parent::redirect(array('site/login'));
} else {
parent::runAction($action);
}
}
}
Everything explained will work for REST requests via the same browser in which the user has logged onto Yii. If you will have the need to expose your REST service to consumers that are not a browser logged into Yii, I believe you would have to come up with a custom authentication/token scheme.
Upvotes: 3