On my D8 site I want to redirect all users to an internal URL after they login. below is my snippet:
function mymodule_user_login($account) {
$url = Url::fromUri('internal:/dashboard-overview');
$response = new RedirectResponse($url->toString());
$response->send();
}
This snippet redirects to "Access denied" error page even for administrators. There is no permission set to visit this URL. Still the page is not loading even for admins. Any help ?
Have you tried this module? https://www.drupal.org/project/redirect_after_login
i think it will do the task you are looking for.
Drupal 8 and 9
You need to alter the login form and add a submit handler which will take care of the redirection. You cannot use $form_state->setRedirectUrl() directly in the form alter, since it will be overwritten by UserForm::submitForm().
/**
* Implements hook_form_FORM_ID_alter().
*/
function mymodule_form_user_login_form_alter(&$form, FormStateInterface $form_state) {
$form['#submit'][] = 'mymodule_user_login_submit';
}
/**
* Form submission handler for user_login_form().
*
* Redirects the user to the dashboard after logging in.
*/
function mymodule_user_login_submit(&$form, FormStateInterface $form_state) {
$url = Url::fromRoute('mymodule.dashboard');
// Check if a destination was set, probably on an exception controller.
// #see \Drupal\user\Form\UserLoginForm::submitForm()
$request = \Drupal::service('request_stack')->getCurrentRequest();
if (!$request->request->has('destination')) {
$form_state->setRedirectUrl($url);
}
else {
$request->query->set('destination', $request->request->get('destination'));
}
}
I am using laravel dusk to login to a wordpress site using the function below
public function testLoginPage()
{
$this->browse(function (Browser $browser) {
$browser->visit('http://localhost/wordpress/wp-login.php')
->waitFor('#wp-submit')
->value('#user_login', '***')
->value('#user_pass', '***')
->click('#wp-submit')
->waitFor('#footer-thankyou')
->assertSee('Thank you for creating with');
$this->saveCookies($browser);
});
}
and saving the cookie created
protected $cookie_file = 'cookies.txt';
private function saveCookies(Browser $browser) {
$cookies = $browser->driver->manage()->getCookies();
file_put_contents($this->cookie_file, serialize($cookies));
}
private function loadCookies(Browser $browser) {
if (file_exists($this->cookie_file)) {
//Get cookies from storage
$cookies = unserialize(file_get_contents($this->cookie_file));
//Add each cookie to this session
foreach ($cookies as $key => $cookie) {
$browser->driver->manage()->addCookie($cookie);
}
}
}
Now I login successfully and the cookie also gets created
But when I try A page in the admin like the update page I get the error that unable to set cookie (Session info: chrome=86.0.4240.75)
public function testUpdateAllPlugins()
{
$this->browse(function (Browser $browser) {
$this->loadCookies($browser);
$browser->visit('http://localhost/wp-admin/update-core.php')
->waitFor('#plugins-select-all')
->check('#plugins-select-all')
->click('#upgrade-plugins')
#->withinFrame('iframe[title="Update progress"]', function($browser){
->withinFrame('.wrap > iframe', function($browser){
$browser
->assertSee('All updates have been completed');
});
});
}
I need to be able to visit all the admin pages after the login so My question is How Do I set and use the cookie from the laravel dusk to wordpress site.
I am using the below namespace in the testcase
namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;
use Facebook\WebDriver\Cookie;
use Facebook\WebDriver\WebDriverOptions;
use Laravel\Dusk\Chrome\ChromeProcess;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Chrome\ChromeOptions;
use Facebook\WebDriver\Remote\DesiredCapabilities;
I got it working using the code for the visit right after the login one instead of setting a cookie and using a different method to visit the browser.
I am using FosUserBundle in Symfony 3.4. I want to redirect users based on their roles. For example, if the role is Client, the user will be redirected to the clients page. If the user is an Admin, then the user will be redirected to the admin dashboard page. How can I do this with FosUserBundle?
Redirect them both to a controller named indexAction() and Redirect them in the controller based on the role. Something like this:
/**
* #Route("/secure-area", name="homepage")
*/
public function indexAction()
{
if($this->getUser()->hasRole('ROLE_ADMIN'))
return $this->redirect($this->generateUrl('admin_area'));
elseif($this->getUser()->hasRole('ROLE_USER'))
return $this->redirect($this->generateUrl('client_area'));
throw new \Exception(AccessDeniedException::class);
}
EDIT:
You should set the default_target_path to the path above
I'm currently using Flow Router to manage page loads. On sign-in I would like to check if the users account has been 'activated by admin' and direct them to one of two pages.
Scenario 1 - User account not active, send user to profile.html
Scenario 2 - User account active, send user to blog.html
I can't find any examples only, could someone please tell me how to do it or direct me to an example I could follow. Thanks!
you can use Accounts.validateLoginAttempt hook on server side like this.
Accounts.validateLoginAttempt(function(attempt) {
if( ! attempt.user || ! attempt.user.profile.status.isActive){
return false;
} else {
return true;
}
});
And this is how you can redirect to user if not active on client side.
Meteor.loginWithPassword(user, password, function( err, res ){
if(err){
//redirect to login or other route
} else {
//redirect to dashboard
}
});
i would like to do something like that in controller to log user out:
$user = $this->get('security.context')->getToken()->getUser();
$user->logOut();
Logout in Symfony2 is handled by so called logout handler which is just a lister that is executed when URL match pattern from security configuration, ie. if URL is let's say /logout then this listener is executed. There are two build-in logout handlers:
CookieClearingLogoutHandler which simply clears all cookies.
SessionLogoutHandler which invalidates the session
All you have to do is the very same the last one does. You can achieve it by simply calling:
Legacy Symfony
$this->get('security.context')->setToken(null);
$this->get('request')->getSession()->invalidate();
Symfony 2.6
$this->get('security.token_storage')->setToken(null);
$this->get('request')->getSession()->invalidate();
Warning
This will only work when remember me functionality is disabled. In other case, user will be logged in back again by means of a remember me cookie with the next request.
Please consider the extended solution if you are using remember me functionality: https://stackoverflow.com/a/28828377/1056679
Invalidating the user's session might cause some unwanted results. Symfony's firewall has a listener that always checks and refreshes the user's token. You could just do a redirect to the default logout route that you have specified in your firewall.yml (or security.yaml)
In Controller you can do this:
$this->redirect($this->generateUrl('your_logout_url'));
If you don't know the name of the logout route (your_logout_url), you can get it from the Symfony console by using this command:
app/console router:match /logout
Or newer Symfony versions:
bin/console router:match /logout
:)
We have to set user as an anonymous user when logging out. Then we can use
$token->getUser()->getRoles(); in controller or {% if is_granted('ROLE_USER') %} in the twig template.
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
...
//$providerKey = $this->container->getParameter('fos_user.firewall_name');
$token = new AnonymousToken($providerKey, 'anon.');
$this->get('security.context')->setToken($token);
$this->get('request')->getSession()->invalidate();
If rememberme functionality is enabled for your site you should also clean rememberme cookie:
$this->get('security.context')->setToken(null);
$this->get('request')->getSession()->invalidate();
$response = new RedirectResponse($this->generateUrl('dn_send_me_the_bundle_confirm', array(
'token' => $token
)));
// Clearing the cookies.
$cookieNames = [
$this->container->getParameter('session.name'),
$this->container->getParameter('session.remember_me.name'),
];
foreach ($cookieNames as $cookieName) {
$response->headers->clearCookie($cookieName);
}
In Symfony 4/5 this is just enough to remove user:
/**
* #var TokenStorageInterface $token_storage
*/
private TokenStorageInterface $token_storage;
/**
* Will force logout from system
*/
public function logoutCurrentlyLoggedInUser()
{
$this->token_storage->setToken(null);
}
Now You can create a method to use it later to check if user is logged in:
class Application extends AbstractController {...
/**
* Returns currently logged in user
* #return object|UserInterface|null
*/
public function getCurrentlyLoggedInUser()
{
return $this->getUser();
}
In case you are using symfony 4.x (I haven't tested other versions, so it still might work), you may want to use the internal logout handler of symfony (highly recommended, as it will take care of everything for you in a clean way, cookies and all). You don't need to write too much code for that either, you can simply emulate a logout request:
... // Some code, that leads you to force logout the user
// Emulating logout request
$logoutPath = $this->container->get('router')->generate('app_logout');
$logoutRequest = Request::create($logoutPath);
$logoutResponse = $this->container->get('http_kernel')->handle($logoutRequest);
// User is logged out now
... // Stuff to do after logging out, eg returning response
This will make symfony do the request response flow, thus it will call the logout handler internally. This method allows you to proceed to further custom code. Otherwise, if you invoked only the logout listener here, you would have to return the usual logout response, that now is in $logoutResponse. Optionally, if you want to return it, you would also simply:
return $logoutResponse;
The proposed solutions didn't work for me in Symfony 5.3.
It should be something as basic as
session_start();
session_destroy();
So I did this way:
$this->get('session')->start();
$this->get('session')->invalidate();
This will terminate the PHP Session, which is the way most of sessions work in Symfony.