Yii 2 redirecting to Login if Guest visit the website - redirect

I need some advice how to make redirecting to login if someone does not login into the website and he is only Guest

use Yii;
use \yii\helpers\Url;
if ( Yii::$app->user->isGuest )
return Yii::$app->getResponse()->redirect(array(Url::to(['site/login'],302)));
Use can use it in actions or views , but if you need to use it in lots of actions you probably need look at AccessControl and restrict access even before action is fired

There are two options:
You can use the AccessControl as mentioned by #Maksym Semenykhin
You can use the option below especially when you would like the logged user to be returned to this page after login.
public function beforeAction($action){
if (parent::beforeAction($action)){
if (Yii::$app->user->isGuest){
Yii::$app->user->loginUrl = ['/auth/default/index', 'return' => \Yii::$app->request->url];
return $this->redirect(Yii::$app->user->loginUrl)->send();
}
}}
You can also create a custom 'Controller' class which inherits \yii\web\Controller then have all controllers that need authorization inherit your custom controller.
On the login function, replace the redirect part with the following code:
$return_url = empty(Yii::$app->request->get('return'))? \yii\helpers\Url::to(['/admin/default/index']) :Yii::$app->request->get('return');
return $this->redirect($return_url);

Use the access section to set access to various actions in the controller.
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
'access' => [
'class' => \yii\filters\AccessControl::className(),
'only' => ['create', 'update','index'],
'rules' => [
// deny all POST requests
[
'allow' => false,
'verbs' => ['POST']
],
// allow authenticated users
[
'allow' => true,
'roles' => ['#'],
],
// everything else is denied
],
],
];
}

works for me.
use Yii;
use \yii\helpers\Url;
if ( Yii::$app->user->isGuest )
return Yii::$app->getResponse()->redirect(array(Url::to(['site/login'])));

The Access Control Filter will do the work for you and redirects you to the configured user->loginUrl (config/main.php) if an action is not allowed.
Add the rule:
array('deny',
'users'=>array('?'),
),
To your base controller (f.e. ‘Controller’) where all your controllers are inherited from.

I used index.php in my web/admin directory
This is the sample my index.php
<?php
// comment out the following two lines when deployed to production
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require __DIR__ . '/../../vendor/autoload.php';
require __DIR__ . '/../../vendor/yiisoft/yii2/Yii.php';
$config = require __DIR__ . '/../../config/web.php';
$config["controllerNamespace"]='app\controllers\backend';
(new yii\web\Application($config))->run();
if(Yii::$app->user->isGuest){
$request_headers = apache_request_headers();
$srv=$request_headers['Host'];
header("Location: https://".$srv);
die();
}

Related

Aura Router AJAX Route Failure - Route Not Found

To preface this question, I'm converting a demo application to utilize RESTful, SEO-friendly URLs; EVERY route with the exception of one of two routes used for AJAX requests works when being used in the application on the web, and ALL the routes have been completely tested using Postman - using a vanilla Nginx configuration.
That being said, here is the offending route definition(s) - the login being the defined route that's failing:
$routing_map->post('login.read', '/services/authentication/login', [
'params' => [
'values' => [
'controller' => '\Infraweb\Toolkit\Services\Authentication',
'action' => 'login',
]
]
])->accepts([
'application/json',
]);
$routing_map->get('logout.read', '/services/authentication/logout', [
'params' => [
'values' => [
'controller' => '\Infraweb\Toolkit\Services\Authentication',
'action' => 'logout',
]
]
])->accepts([
'application/json',
]);
With Postman & xdebug tracing I think I'm seeing that it's (obviously) failing what I believe to be a REGEX check in the Path rule, but I can't quite make it out. It's frustrating to say the least. I looked everywhere I could using web searches before posting here - the Google group for Auraphp doesn't seem to get much traffic these days. It's probable I've done something incorrectly, so I figured it was time to ask the collective user community for some direction. Any and all constructive criticism is greatly welcomed and appreciated.
Thanx in advance, and apologies for wasting anyone's bandwidth on this question...
Let me make something clear. Aura.Router doesn't do the dispatching. It only matches the route. It doesn't handle how your routes are handled.
See the full working example ( In that example the handler is assumed as callable )
$callable = $route->handler;
$response = $callable($request);
In your case if you matched the request ( See matching request )
$matcher = $routerContainer->getMatcher();
$route = $matcher->match($request);
you will get the route, now you need to write appropriate ways how to handle the values from the $route->handler.
This is what I did after var_dump the $route->handler for the /signin route .
array (size=1)
'params' =>
array (size=1)
'values' =>
array (size=2)
'controller' => string '\Infraweb\LoginUI' (length=17)
'action' => string 'read' (length=4)
Full code tried below. As I mentioned before I don't know your route handling logic. So it is up to you to write things properly.
<?php
require __DIR__ . '/vendor/autoload.php';
use Aura\Router\RouterContainer;
$routerContainer = new RouterContainer();
$map = $routerContainer->getMap();
$request = Zend\Diactoros\ServerRequestFactory::fromGlobals(
$_SERVER,
$_GET,
$_POST,
$_COOKIE,
$_FILES
);
$map->get('application.signin.read', '/signin', [
'params' => [
'values' => [
'controller' => '\Infraweb\LoginUI',
'action' => 'read',
]
]
]);
$map->post('login.read', '/services/authentication/login', [
'params' => [
'values' => [
'controller' => '\Infraweb\Toolkit\Services\Authentication',
'action' => 'login',
]
]
])->accepts([
'application/json',
]);
$matcher = $routerContainer->getMatcher();
// .. and try to match the request to a route.
$route = $matcher->match($request);
if (! $route) {
echo "No route found for the request.";
exit;
}
echo '<pre>';
var_dump($route->handler);
exit;
For the record, this is the composer.json
{
"require": {
"aura/router": "^3.1",
"zendframework/zend-diactoros": "^2.1"
}
}
and running via
php -S localhost:8000 index.php
and browsing http://localhost:8000/signin

No permissions on dektrium user admin index action

I installed dektrium user but when override the AdminController.php and tried to reach admin/index what I get is Forbidden(403). After overriding the behaviors to:
'rules' => [
[
'allow' => true,
'roles' => ['?'],
],
],
the error is still the same. Did this because I still don't have any roles. What can cause this behavior ? I am aiming at the origin index.php ( the one in the dektrium\yii2-user module). Thank you!
You need to follow these rules to override controllers for dektrium-user
directory structure
You can change the following if you want it into the frontend, only starting folder needs to be changed
- backend
- controllers
- user
- AdminController
Your config for the user module under the module section should look like following
'modules' => [
..............
'user' => [
'controllerMap' => [
'admin' => 'backend\controllers\user\AdminController' ,
] ,
For overriding the controller with a new action index your minimum code should look like below
AdminController
<?php
namespace backend\controllers\user;
use dektrium\user\controllers\AdminController as BaseAdmin;
class AdminController extends BaseAdmin {
public function behaviors() {
$behaviours = parent::behaviors ();
$behaviours['access']['rules'][] = [
'allow' => true ,
'actions' => [ 'index' ] ,
'roles' => [ '?' ]
];
return $behaviours;
}
public function actionIndex(){
return $this->render('index');
}
}

Laravel 5.5 - laravel/socialite scopes and redirect

Can somebody explain to me what are scopes in laravel/socialite and how can I define multiple redirect from services.php
I need one for sign up with facebook, and another for login with facebook
config/services.php
'facebook' => [
'client_id' => '***************',
'client_secret' => '****************',
'redirectForSignUp' => 'http://localhost:8000/register/facebook/callback',
'redirectForLogin' => 'http://localhost:8000/login/facebook/callback',
],
The solution to this is:
public function redirectToProvider($accountType, $provider)
{
return Socialite::driver($provider)
->with(['redirect_uri' => "http://localhost:8000/api/auth/{$accountType}/{$provider}/callback/"])
->redirect();
}
You could use this method to replace anything in the http request url (including scopes).
To override other things like scopes, simply:
->with([scopes => 'SCOPES HERE', redirect_url => ''])
->redirect();
Open your .env file and set following value in it bottom
FACEBOOK_CLIENT_ID=xxxxxxxxx
FACEBOOK_CLIENT_SECRET=xxxxxxx
CALLBACK_URL=http://localhost:8000/auth/facebook/callback
Then after opwn config/services.php file and set following value
'facebook' => [
'client_id' => env('FACEBOOK_CLIENT_ID'),
'client_secret' => env('FACEBOOK_CLIENT_SECRET'),
'redirect' => env('CALLBACK_URL'),
],
Visit thiss link for full laravel/socialite configuration in laravel application
http://laravelcode.com/post/laravel54-login-with-facebook-in-laravel

How to check if authenticated user is handler of REST resourece

I've developing a REST service on Yii2 and Angular 2 client. Using Bearer JWT authentication.
For example there is a uri: http://127.0.0.1/v1/accounts/123456/meters, which should return all user's meters by account, which he own.
Applied router rule:
'<accountId:\w+>/<action:[\w-]+>' => '<action>',
Controllers has following behaviors:
'authenticator' => [
'class' => HttpBearerAuth::className(),
'except' => ['options']
],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'actions' => ['meters'],
'roles' => ['#'],
]
]
]
Action AccountController::actionMeters looks:
public function actionMeters($accountId)
{
// Call MS SQL procedure
$meters = Yii::$app->db->createCommand("EXEC [getMetersByAccountId] :accountId")->bindValue(':accountId', $accountId)->queryAll()
return $meters;
}
But in this way authenticated user can get (if modify GET accountId parameter) meters, which belongs to another user.
I have a user_account table in database, which link users and accounts, but I don't know in which place of application should I perform a checking properly.
How to make a check if authenticated user has an access to this resource by specified accountId parameter?
Thank you.
I've found solution to determine matchCallback in access rule. Now it's look:
[
'allow' => true,
'actions' => ['meters'],
'roles' => ['#'],
'matchCallback' => function() {
return Yii::$app->user->identity->user->hasAccount(Yii::$app->request->get('accountId'));
}
],
And define hasAccount method in User model:
public function hasAccount($accountId) {
return $this->hasOne(UserAccount::className(), ['user_id' => 'id'])->where(['account_id' => $accountId])->exists();
}
It's work correct. Is it a proper solution?

Yii2 restful not working

By using this link I tried to have a restful app, but it's not working and always returned this:
Object not found!
The requested URL was not found on this server. If you entered the URL manually please > > check your spelling and try again.
If you think this is a server error, please contact the webmaster.
Error 404
localhost
Apache/2.4.4 (Win32) OpenSSL/1.0.1e PHP/5.5.1
I call it like this: localhost/restful/web/users
Edit:
This kind of call is not working either: localhost/restful/web/?r=users
It returned this:
Not Found (#404)
Page not found.
The above error occurred while the Web server was processing your request.
Please contact us if you think this is a server error. Thank you.
Have the same error (stil getting 404 Not found on each request) have solve it adding .htaccess to (my yii path)/web folder (the same where you have index.php):
# use mod_rewrite for pretty URL support
RewriteEngine on
# If a directory or a file exists, use the request directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Otherwise forward the request to index.php
RewriteRule . index.php
This is because when you create an clean instance of Yii2 you don't have the .htaccess file (in my opinion probably the security reason).
for me the: (enabling curl and using it in my controller) installed via composer
composer require --prefer-dist linslin/yii2-curl "*"
use in controller
<?php
namespace app\controllers;
use yii\rest\ActiveController;
use linslin\yii2\curl;//this was added
class UserController extends ActiveController
{
Don't work.
Maybe this helps someone :)
This is my config/web.php:
<?php
$params = require(__DIR__ . '/params.php');
$config = [
'id' => 'basic',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'components' => [
'urlManager'=>[
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule', 'controller' => 'user'],
],
],
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => 'a',
'parsers' => [
'application/json' => 'yii\web\JsonParser',
],
],
'cache' => [
'class' => 'yii\caching\FileCache',
],
'user' => [
'identityClass' => 'app\models\User',
'enableAutoLogin' => true,
],
'errorHandler' => [
'errorAction' => 'site/error',
],
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
// send all mails to a file by default. You have to set
// 'useFileTransport' to false and configure a transport
// for the mailer to send real emails.
'useFileTransport' => true,
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'db' => require(__DIR__ . '/db.php'),
],
'params' => $params,
];
if (YII_ENV_DEV) {
// configuration adjustments for 'dev' environment
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = 'yii\debug\Module';
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = 'yii\gii\Module';
}
return $config;
And the controller:
<?php
namespace app\controllers;
use yii\rest\ActiveController;
class UserController extends ActiveController{
public $modelClass = 'app\models\User';
}
Also a created my model by gii.
The problem solved by enabling curl and using it in my controller.