Make node only accesible by path alias I was wondering if it's possible to make nodes without path alias not accessible. By this I mean that visiting /node/$nid/ users will not be able to see its content, but if that node has an path alias (e.g. /myarticle/my-article-name/) the node will be visible using the path alias.

Is it possible to achieve it with code?

By researching, I found that I can do this in hook_menu() with either
 $items['node/%node']['page callback'] = 'drupal_not_found'; or $items['node/%node']['access'] = FALSE;.

The problem is that I can't access with /node/$nid/ and without /myarticle/my-article-name/, it raises permission denied.
hook_menu() is not the hook to alter the routes defined from other modules, but in this case not even hook_menu_alter() would help.

When users access a page using a path alias, Drupal gets the normal path (i.e. the path to which the path alias points) before rendering the page. So, for Drupal, users are always visiting /node/$nid, not /myarticle/my-article-name/. In fact, drupal_path_initialize() (called at bootstrap time) contains the following code.

  if (empty($_GET['q'])) {
    $_GET['q'] = variable_get('site_frontpage', 'node');
  }
  $_GET['q'] = drupal_get_normal_path($_GET['q']);


drupal_get_normal_path() is the function converting the path alias in the internal path.

In this case, a redirect from /node/$nid to /myarticle/my-article-name/ is, IMO, the solution. The Global Redirect module already does that, as the project page describes.


  
  Checks the current URL for an alias and does a 301 redirect to it if it is not being used.  
  Checks the current URL for a trailing slash, removes it if present and repeats check 1 with the new request.
  


Also, notice the Why? section on that page.


  Once enabled, an alias provides a nice clean URL for a path on a site. However Drupal does not remove the old path (eg node/1234). The problem is that you now have two URLs representing the same content. This is dangerous territory for duplicate pages which can get you sandboxed by the search engines!