Trying to implement a GET method in Rest API, to query the user status e.g. GET user/:id/status
So getting the status of user id #1 would call /user/1/status
In config I have:
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => [
'v1/user'
],
'extraPatterns' => [
'GET status' => 'status',
],
'tokens' => [
'{id}' => '<id:\\w+>'
],
],
],
User Model:
namespace api\modules\v1\models;
use \yii\db\ActiveRecord;
class User extends ActiveRecord {
/**
* #inheritdoc
*/
public static function tableName() {
return 'user';
}
/**
* #inheritdoc
*/
public static function primaryKey() {
return [ 'id' ];
}
}
User Controller:
namespace api\modules\v1\controllers;
use yii\rest\ActiveController;
class UserController extends ActiveController {
public $modelClass = 'api\modules\v1\models\User';
public function actions() {
$actions = parent::actions();
unset(
$actions[ 'index' ],
$actions[ 'view' ],
$actions[ 'create' ],
$actions[ 'update' ],
$actions[ 'delete' ],
$actions[ 'options' ]
);
return $actions;
}
protected function verbs() {
return [
'status' => [ 'GET' ],
];
}
public function actionStatus( $id ) {
return 1;
}
}
But now I'm not sure on how to actually return the data for the call.
$user = User::findOne($id);
if ($user)
return Json::encode(['success'=>true, 'data'=>$user->status]);
else
return Json::encode(['success'=>false, 'message'=>"Can't find user"]);
Related
For example? I have two BaseController and ChildController.
I want attach behaviors from BaseController, but priority has behaviors(Base), when behaviors(Child).
Base:
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'matchCallback' => function ($rule, $action) {
return ...(true or false)...;
}
],
],
],
];
}
Child:
[
'allow' => true,
'roles' => ['admin'],
'matchCallback' => function($rule, $action) {
return ... can...
}
],
and logic:
if parent return false then access denied
if parent return true then what return child
how?
This must help you
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['access'] = [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'matchCallback' => function ($rule, $action) {
return ... can ...;
},
],
],
];
return $behaviors;
}
other way could be:
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['access']['rules'][] = [
'allow' => true,
'matchCallback' => function ($rule, $action) {
return ... can ...;
},
];
return $behaviors;
}
I am working on API in Yii2, where I need to use different authentication methods for different actions.
How can I set CompositeAuth for action1, action2 and action3, and HttpBasicAuth for action4 and action5?
public function behaviors()
{
return [
'basicAuth' => [
'class' => \yii\filters\auth\HttpBasicAuth::className(),
'auth' => function ($username, $password) {
$user = User::find()->where(['username' => $username])->one();
if ($user->verifyPassword($password)) {
return $user;
}
return null;
},
],
];
}
You can attach multiple auth behaviors and use only property to specify list of actions which should be affected by each behavior:
public function behaviors() {
return [
'compositeAuth' => [
'class' => \yii\filters\auth\CompositeAuth::className(),
'authMethods' => [/* ... */],
'only' => ['action1', 'action2', 'action3'],
],
'basicAuth' => [
'class' => \yii\filters\auth\HttpBasicAuth::className(),
'auth' => function ($username, $password) {
$user = User::find()->where(['username' => $username])->one();
if ($user->verifyPassword($password)) {
return $user;
}
return null;
},
'only' => ['action4', 'action5'],
],
];
}
How I can restrict access to RBAC Module itself?
I'm using yii\rbac\DbManager and I have created a module(Authorization) in backend for permission assignment,create auth items, now I want to make sure only admin can access this module!
In controller I have used something this and it's working fine.
use yii\filters\AccessControl;
class MyController extends Controller
{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['index', 'view', 'create', 'update', 'delete'], //only be applied to
'rules' => [
[
'allow' => true,
'actions' => ['index', 'view', 'create', 'update','delete'],
'roles' => ['admin'],
],
],
],
.........
I have put this in Authorization.php init function but nothing happen, all auth controllers are accessable.
public function init()
{
if(\Yii::$app->user->can('admin'))
parent::init();
// custom initialization code goes here
}
Update
backend/config/main.php
'modules' => [
'authorization' => [
'class' => 'backend\modules\authorization\Authorization',
],
],
In your module class you can add this method
public function beforeAction($action)
{
if (!parent::beforeAction($action)) {
return false;
}
if (!\Yii::$app->user->can('admin')) {
throw new \yii\web\ForbiddenHttpException('You are not allowed to access this page.');
}
return true;
}
I have this controller code for login:
public function actionLogin()
{
if (!\Yii::$app->user->isGuest) {
return $this->redirect(Yii::$app->request->baseUrl.'/telephone/index');
}
$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->login()) {
return $this->redirect(Yii::$app->request->baseUrl.'/telephone/index');
}
return $this->render('login', [
'model' => $model,
]);
}
And for preventing the add and delete action for unauthorized users i used:
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['add','delete'],
'rules' => [
// allow authenticated users
[
'allow' => true,
'roles' => ['#'],
],
// everything else is denied by default
],
],
];
}
But if unauthorized users clik add or delete, it is redirected to site/login. How can i change that controller and action?
There are different approaches to changing that route depending on the scope. They all involve changing the loginUrl property of the yii\web\User class.
Global
Edit config file.
'components' => [
'user' => [
'loginUrl' => ["controller/action"],
],
],
Controller/Action
Edit beforeAction method of the controller.
public function beforeAction($action)
{
// action-specific
if(in_array($action->id,['not', 'allowed', 'actions']))
Yii::$app->user->loginUrl = ["controller/action"];
// controller-wide
Yii::$app->user->loginUrl = ["controller/action"];
if (!parent::beforeAction($action)) {
return false;
}
return true;
}
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['add','delete'],
'rules' => [
'allow' => true,
'actions' => ['add','delete'],
'roles' => ['#'],
'denyCallback' => function ($rule, $action) {
return $this->redirect('index.php?r=site/login');
}
],
],
];
}
Does anyone have a working example of this extension.
I'm talking about:
https://github.com/mdmsoft/yii2-admin
I'm looking for Yii app basic.
I installed and working properly, but I don't know how to configure "Roles" and "Rules"
At Yii 1.xxx I used http://www.yiiframework.com/extension/authbooster/ but this not working in Yii2.xx
Create a custom model AccessRules.php
<?php
namespace app\models;
class AccessRules extends \yii\filters\AccessRule
{
/**
* #inheritdoc
*/
protected function matchRole($user)
{
if (empty($this->roles)) {
return true;
}
foreach ($this->roles as $role) {
if ($role === '?') {
if ($user->getIsGuest()) {
return true;
}
} elseif ($role === '#') {
if (!$user->getIsGuest()) {
return true;
}
// Check if the user is logged in, and the roles match
} elseif (!$user->getIsGuest() && (int)$role === $user->identity->user_role) {
return true;
}
}
return false;
}
}
?>
Now in your Site Controller add the roles:
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
// We will override the default rule config with the new AccessRule class
'ruleConfig' => [
'class' => AccessRules::className(),
],
'only' => ['create', 'update', 'delete','index'],
'rules' => [
[
'actions' => ['create', 'update', 'delete','index'],
'allow' => true,
// Allow admin to create
'roles' => [
'1'
],
]
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}