2

I am working on a custom Drupal 8 module that has its own authentication form.

For this, I created a Drupal page with the custom authentication form, i.e. I have a route at drupalsite.com/custom-signup

What I am not able to figure out is how can I replace Drupal's default Register and Login links which are scattered everywhere on the website to point to above route. I don't want to redirect from /user/login page to /custom-signup as I still want to allow admin to login. For all other users except admins should be redirected to \custom-signup.

I could use jquery to brute-force my way to replace the links, but is there an efficient way to achieve this?

TL;DR: I need to replace following default Drupal links using my module.

enter image description here

Update:

Following the first solution, I added the routing files as follows, the links are redirecting me to my custom form.

enter image description here

However, when I try to enter user/login manually in the URL, I get page not found message on the website. enter image description here

  • You could just change the user auth class from core to your own implementation. When checking authentication, if the username/email matches user id 1 or a certain role, you can let Drupal just authenticate it without using the external service or however you are implementing new authentication. – Kevin Dec 8 '17 at 18:53
  • I understand what you are saying, not sure how to implement it. Can you please point me to some sample code on overriding core classes to my own? – Akshay Khot Dec 8 '17 at 19:14
3

You need to alter the route, in your custom module add:

mymodule/src/Routing/RouteSubscriber.php

namespace Drupal\mymodule\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

/**
 * Listens to the dynamic route events.
 */
class RouteSubscriber extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {
    // Change path '/user/login' to '/customn-login'.
    if ($route = $collection->get('user.login')) {
      $route->setPath('/custom-login');
    }
    // Change path '/user/register' to '/custom-signup'.
    if ($route = $collection->get('user.register')) {
      $route->setPath('/custom-signup');
    }
  }

}

mymodule/mymodule.services.yml

services:
  mymodule.route_subscriber:
    class: Drupal\mymodule\Routing\RouteSubscriber
    tags:
      - { name: event_subscriber }

For more in depth information, see Altering existing routes and adding new routes based on dynamic ones.


If you still want /user/login to work, then you can create a new route for it.

mymodule/mymodule.routing.yml

mymodule.login:
  path: '/user/login'
  defaults:
    _form: '\Drupal\user\Form\UserLoginForm'
    _title: 'Log in'
  requirements:
    _user_is_logged_in: 'FALSE'
  options:
    _maintenance_access: TRUE

Remember to clear all caches to see changes.

  • Thank you. When I try to go to /user/login I get the requested page could not be found error, even though I can navigate to /custom-login by manually typing in the address bar. – Akshay Khot Dec 8 '17 at 18:21
  • If I use $route->setPath('/user/login'), i.e. replacing the user/login with itself, it works. That means the code is working, but it's not able to find the /custom-login path. – Akshay Khot Dec 8 '17 at 18:24
  • So you want to still have /user/login path so admins can login there and a /custom-login path for everyone else? – No Sssweat Dec 8 '17 at 22:30
  • Exactly. I tried the above solution, but somehow it's not redirecting me to /custom-login. – Akshay Khot Dec 8 '17 at 23:20
  • 1
    That's genius. It's working exactly as I wanted it to work. I wish I could mark this twice as an answer. Thank you so much for your help with this, really appreciate it. – Akshay Khot Dec 9 '17 at 0:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.