# Redirection adds '#' to end of URL

**URL:** <https://discourse.slimframework.com/t/redirection-adds-to-end-of-url/5023>\
**Category:** Questions\
**Created:** [November 29, 2021, 7:28pm UTC](https://discourse.slimframework.com/t/redirection-adds-to-end-of-url/5023 "2021-11-29T19:28:38Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![abid-aldisa](https://avatars.discourse-cdn.com/v4/letter/a/3da27b/32.png) [@abid-aldisa](https://discourse.slimframework.com/u/abid-aldisa)\
**Post date:** [November 29, 2021, 7:28pm UTC](https://discourse.slimframework.com/t/redirection-adds-to-end-of-url/5023/1 "2021-11-29T19:28:38Z")

</div>

I am using Slim 4 with PHP 7.3 on a Debian 10 VM instance in the Google Cloud.

I have written a custom Auth Handler and Auth Controller that relies of Microsoft MSAL and Graph for User Authentication.

Whenever the authentication process cycles through the MSAL auth process, it sends the browser back to the /auth/callback route. The redirect in this route gets a hash character appended to it. I have added logging immediately before the redirect, and the URL variable `$redirectURL` does not contain the hash character.

Below are the relevant snippets of my code.

UserAuthMiddleware

```auto
class UserAuthMiddleware implements Middleware
{
    private $session;
    private $user;

    public function __construct(Session $session, User $user)
    {
        $this->session = $session;
        $this->user = $user;
    }

    public function __invoke(Request $request, Handler $handler): Response
    {
        return $this->process($request, $handler);
    }

    public function process(Request $request, Handler $handler): Response
    {
        if ($this->session->exists('user') && false !== $this->session->get('user')) {
            $request = $request->withAttribute('user', $this->user);
            return $handler->handle($request);
        }
        
        $this->session->set('userauthroute', $request->getUri()->getPath());
        $factory = new ResponseFactory;
        $response = $factory->createResponse();
        return $response
            ->withStatus(302)
            ->withHeader('Location', RouteContext::fromRequest($request)->getRouteParser()->urlFor('login'));
    }
}

```

UserAuthController

```auto
class UserAuthController
{
    private $container;
    private $responseFactory;
    private $session;

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
        $this->responseFactory = new ResponseFactory();
        $this->session = $container->get('session');
    }

    public function login(Request $request, Response $response, $args): Response
    {
        $provider = $this->getProvider($request);
        $authURL = $provider->getAuthorizationUrl(['scope' => ['User.Read']]);

        $this->session->set('oauth2state', $provider->getState());
        $this->session->set('user', false);
        
        return $this->responseFactory->createResponse()
            ->withHeader('Location', $authURL)
            ->withStatus(302);
    }

    public function callback(Request $request, Response $response, $args): Response
    {
        $params = $request->getQueryParams();

        if (!array_key_exists('code', $params) || !array_key_exists('state', $params)) {
            throw new UserAuthException("Invalid Callback Request");
        }

        if (!$this->session->exists('oauth2state') || $this->session->get('oauth2state') !== $params['state']) {
            throw new UserAuthException("Callback State Error");
        }
        $this->session->delete('oauth2state');

        $provider = $this->getProvider($request);
        $token = $provider->getAccessToken('authorization_code', ['code' => $params['code']]);

        $graph = new Graph();
        $graph->setAccessToken($token->getToken());
        $user = $graph->createRequest("GET", "/me")->setReturnType(Model\User::class)->execute();
        $this->session->set('user', $user->getMail());

        if ($this->session->exists('userauthroute')) {
            $redirectURL = $this->session->get('userauthroute');
            $this->session->delete('userauthroute');
        } else {
            $redirectURL = RouteContext::fromRequest($request)->getRouteParser()->urlFor('home');
        }

        $logger = LoggerFactory::create('info');
        $logger->info($redirectURL);

        return $this->responseFactory->createResponse()
            ->withHeader('Location', $redirectURL)
            ->withStatus(302);
    }

    public function logout(Request $request, Response $response, $args): Response
    {
        $this->session->set('user', false);
        return $this->container->get('view')->render($response, 'logout.twig');
    }

    private function getProvider($request): Provider
    {
        $uri = $request->getUri();
        $callbackUrl = RouteContext::fromRequest($request)->getRouteParser()->fullUrlFor($uri, 'callback');
        $options = array_merge($this->container->get('MSAL_Config'), ['redirectUrl' => $callbackUrl]);
        return new Provider($options);
    }
}

```

routes.php

```auto
    // MSAL User Auth Routes
    $app->group('/auth', function (RouteCollectorProxy $group) use ($app) {
        $group->get('/login', [UserAuthController::class, 'login'])->setName('login');
        $group->get('/callback', [UserAuthController::class, 'callback'])->setName('callback');
        $group->get('/logout', [UserAuthController::class, 'logout'])->setName('logout')->add(TwigMiddleware::createFromContainer($app));
    });

```

I will be grateful if anyone can help me figure out why and where the hash character is being appended, and what I can do to prevent this from happening.

---

<div class="post-metadata">

**Author:** ![abid-aldisa](https://avatars.discourse-cdn.com/v4/letter/a/3da27b/32.png) [@abid-aldisa](https://discourse.slimframework.com/u/abid-aldisa)\
**Post date:** [November 30, 2021, 6:55pm UTC](https://discourse.slimframework.com/t/redirection-adds-to-end-of-url/5023/2 "2021-11-30T18:55:45Z")

</div>

I have discovered that the Microsoft MSAL service is appending the “#” character to the callback url when it returns after processing the authentication.  
[https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/1579](https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/1579)

So, instead of sending back to `https://<domain>/auth/callback`, it is sending back to `https://<domain>/auth/callback#`

I have also tested that when Slim processes a redirect response where the current request url contains a “#” at the end of the url, it adds the hash to the redirect url as well.

Any guidance about how to remove the fragment portion in a redirect when generating the response would be greatly appreciated.

---

<div class="post-metadata">

**Author:** ![odan](https://avatars.discourse-cdn.com/v4/letter/o/9de053/32.png) [@odan](https://discourse.slimframework.com/u/odan)\
**Post date:** [December 1, 2021, 1:37pm UTC](https://discourse.slimframework.com/t/redirection-adds-to-end-of-url/5023/3 "2021-12-01T13:37:25Z")

</div>

Hi @abid-aldisa Have you tried this? [Removing anchor (#hash) from URL](https://stackoverflow.com/questions/16773111/removing-anchor-hash-from-url).

Example:

```php
$callbackUrl = strstr($callbackUrl, '#', true);

```

---

<div class="post-metadata">

**Author:** ![abid-aldisa](https://avatars.discourse-cdn.com/v4/letter/a/3da27b/32.png) [@abid-aldisa](https://discourse.slimframework.com/u/abid-aldisa)\
**Post date:** [December 2, 2021, 5:09pm UTC](https://discourse.slimframework.com/t/redirection-adds-to-end-of-url/5023/4 "2021-12-02T17:09:14Z")

</div>

Hello Odan,

Thanks so much for your suggestion. But none of my variables with URLs in them have a hash character. So, using functions to strip the string of the hash fragment does not affect the outcome.

Consider the following code in the routing:

```auto
$app->get('/home', function (Request $request, Response $response, $args) {
    return $this->get('view')->render($response, 'home.twig'));
})->setName('home');

$app->get('/hello', function (Request $request, Response $response, $args) {
    $url = RouteContext::fromRequest($request)->getRouteParser()->urlFor('home');
    return $response->withHeader('Location', $url)->withStatus(302);
});

```

If I enter `https://<domain>/hello` into browser, I am redirected to `https://<domain>/home`. But, if I enter `https://<domain>/hello#` into the browser, I am redirected to `https://<domain>/home#`, even though the $url variable in above code never contains ‘#’ character in it.

This implies that the routing or response emitter at the framework level is capturing the fragment from the Request, even though the url in Response does not have it. Do you have any ideas or suggestions about how I can generate a Redirect Response that ignores the hash character present in the Request?

---

<div class="post-metadata">

**Author:** ![odan](https://avatars.discourse-cdn.com/v4/letter/o/9de053/32.png) [@odan](https://discourse.slimframework.com/u/odan)\
**Post date:** [December 2, 2021, 8:01pm UTC](https://discourse.slimframework.com/t/redirection-adds-to-end-of-url/5023/5 "2021-12-02T20:01:29Z")

</div>

The behavior you are describing is a browser (client) specific behavior. The browser does not send the fragment identifier (hash mark #) to the webserver (php, slim) over http. You can see it if you open the F12 developer toolbar \> Network.

Chrome will append the fragment identifier to the new URI, which generally confuses the user because they end up with the wrong resource.

Until now, Firefox does not add the fragment identifier to the new URI.

Just to let you know, here you can find a proper specification by w3c defining how all should behave:

- [Common User Agent Problems](http://www.w3.org/TR/cuap#uri)

---

<div class="post-metadata">

**Author:** ![abid-aldisa](https://avatars.discourse-cdn.com/v4/letter/a/3da27b/32.png) [@abid-aldisa](https://discourse.slimframework.com/u/abid-aldisa)\
**Post date:** [December 2, 2021, 9:34pm UTC](https://discourse.slimframework.com/t/redirection-adds-to-end-of-url/5023/6 "2021-12-02T21:34:58Z")

</div>

I understand now. Thank you, Odan, for the clarification.

---

<div class="post-metadata">

**Author:** ![HoracioReyes](https://avatars.discourse-cdn.com/v4/letter/h/ce73a5/32.png) [@HoracioReyes](https://discourse.slimframework.com/u/HoracioReyes)\
**Post date:** [August 24, 2022, 12:29pm UTC](https://discourse.slimframework.com/t/redirection-adds-to-end-of-url/5023/7 "2022-08-24T12:29:12Z")

</div>

Dear @abid-aldisa , I’m new in Slim and I’m trying to start a project where I want to check user auth (I supose with a middleware) and when is validate save the user data to be share in all the API REST.  
Could you share your appliczation code please? I din’t found it on github  
Thanks a lot and I sorry for my English
