Welcome Guest, Not a member yet? Register   Sign In
Shield - redirect after login
#1

hi,
i need to protect route 'bookmark/init' and have noticed that after login, user is redirected to '/'. To have him redirected to what he requested : "bookmark/init' my solution is the following, and my question is : is this dumb, and is there a better way ?
My code :
in app\Config\Routes.php
PHP Code:
$routes->get('bookmark/init','Bookmark::init',['filter' => 'perm:users.edit']); 

in app\Config\Filter.php
PHP Code:
public array $aliases = [
        'perm'    => \App\Filters\PermissionFilter::class,
    ]; 

in App\Filters\PermissionFilter.php
PHP Code:
    public function before(RequestInterface $request$params null)
    {
        if (empty($params)) {
        return;
        }

        $uri $request->getUri();
        $req $uri->getQuery();
        $path $uri->getPath();
        service('settings')->set('Auth.redirects', ['login' => $path]);

        if (!function_exists('auth')) helper('auth');
        
        
if (!auth()->loggedIn()) return redirect()->to('login');
        
        $result 
true;

        foreach ($params as $permission$result $result && auth()->user()->can($permission);

        if (!$result) {
            $session service('session');
            $session->setFlashdata('warning',lang('Auth.notEnoughPrivilege'));
            return redirect()->to('/');
        }
        return $result;
    
NOTA :
First : I use alias perm in Routes, because, when you use Permission
PHP Code:
$routes->get('bookmark/init','Bookmark::init',['filter' => 'permission:users.edit']); 
Codeigniter and/or Shield fires Shield permission filter instead of the one in app\Filters, even if Filters.app contains
PHP Code:
public array $aliases = [
        'permission'    => \App\Filters\PermissionFilter::class,
    ]; 
And second, i use settings() because of Config\Auth.php LoginRedirectMethod()
Reply
#2

It is not good. Because the code "service('settings')->set('Auth.redirects', ['login' => $path])" updates the Config value in the database.
That is, the config values is global, and it is shared by all requests.

If a user gets bookmark/init, it sets Auth.redirects to ['login' => 'bookmark/init'].
And after that, all users will be redirected to bookmark/init after logged in.

If you have more than one protected page, this may happen:
1. user A sets Auth.redirects to ['login' => 'bookmark/init']
2. user B sets Auth.redirects to ['login' => 'another']
3. user A is logged in, and redirected to 'another'
4. user B is logged in, and redirected to 'another'
Reply
#3

(04-12-2023, 06:01 AM)kenjis Wrote: It is not good. Because the code "service('settings')->set('Auth.redirects', ['login' => $path])" updates the Config value in the database.
That is, the config values is global, and it is shared by all requests.

If a user gets bookmark/init, it sets Auth.redirects to ['login' => 'bookmark/init'].
And after that, all users will be redirected to bookmark/init after logged in.

If you have more than one protected page, this may happen:
1. user A sets Auth.redirects to ['login' => 'bookmark/init']
2. user B sets Auth.redirects to ['login' => 'another']
3. user A is logged in, and redirected to 'another'
4. user B is logged in, and redirected to 'another'

I understand, and agree, but what is the good way ?
Reply
#4

Anyone? I need this solution too.
Reply
#5

Shield User Guide - Custom Redirect URLs
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#6

(08-06-2023, 11:19 PM)InsiteFX Wrote: Shield User Guide - Custom Redirect URLs

Thanks for help
Have modified my solution (exposed above) :
Url requested by user, before filling the Shield login form, is saved in session in some App\Filters\permissionFilter
And is retrieved (and destroyed) in Shield RedirectAfterLogin() of Auth.php function
Can show code here for those who need
Eric
Reply
#7

Yes, please show the code to help other users learn how to do it.
Thank you.
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#8

When only some routes of app are protected, you might have to find a solution to redirect user after login
In my App, I managed things like this :
First create a filter named permissionFilter.php in directory App\Filters
PHP Code:
<?php
namespace App\Filters;

use 
CodeIgniter\HTTP\RequestInterface;
use 
CodeIgniter\HTTP\ResponseInterface;
use 
CodeIgniter\Filters\FilterInterface;

class 
PermissionFilter implements FilterInterface
{
    public function before(RequestInterface $request$params null)
    {
        $pathsegments $request->getUri()->getSegments();
        $path implode("/"$pathsegments);
        service('session')->set(['redirects' => $path]);

        if (empty($params)) {
        return;
        }
        
        
if (!function_exists('auth')) {
        helper('auth');
        }
        
        
if (!auth()->loggedIn()) {
        return redirect()->to('login');
        }
        
        $result 
true;
        
        
foreach ($params as $permission) {
        $result $result && auth()->user()->can($permission);
        }
        
        
if (!$result) {
            service('session')->setFlashdata('warning',lang('Auth.notEnoughPrivilege'));
            return redirect()->to('/');
        }
 
        return $result;
    
Then, in App\Config\Filters.php you have to set the filter so that the one of Shield doesnot fires first. Its done by using an alias
PHP Code:
<?php

namespace Config;

[...]
use 
App\Filters\PermissionFilter;

class 
Filters extends BaseConfig
{
    /**
    * Configures aliases for Filter classes to
    * make reading things nicer and simpler.
    *
    * @var array<string, string>
    * @phpstan-var array<string, class-string>
    */
    public array $aliases = [
         [...]
        'perm'    => PermissionFilter::class,
    ]; 
In App\Config\Auth.php modify Shield code to get the right route to redirect
PHP Code:
    /**
    * Returns the URL that a user should be redirected
    * to after a successful login.
    */
    public function loginRedirect(): string
    
{
        $session session();
        if ($session->get('redirects') === NULL$url $session->getTempdata('beforeLoginUrl') ?? setting('Auth.redirects')['login'];
        else {
            $url $session->get('redirects');
            $session->remove('redirects');
        }

        return $this->getUrl($url);
    
And then App\Config\Route.php must use the right permissionFilter
PHP Code:
$routes->match(['get','post'],'personne/update/(:num)','Personne::update/$1', ['filter' => 'perm:users.edit']);

Maybe this code is not that beautifulbut hope it will help 
Reply
#9

@foxbille I don't know exactly what the issue is.

Are you looking for a topic similar to the below?

https://github.com/codeigniter4/shield/discussions/722

If yes, it is implemented in branch develop and can be used.
Reply
#10

(09-05-2023, 12:02 PM)datamweb Wrote: @foxbille I don't know exactly what the issue is.

Are you looking for a topic similar to the below?

https://github.com/codeigniter4/shield/discussions/722

If yes, it is implemented in branch develop and can be used.
Thank ! That works pretty well. Was it implemented in a very recent version of Shield ???
Reply




Theme © iAndrew 2016 - Forum software by © MyBB