#Angular 17 - SSR with Cookies

24 messages · Page 1 of 1 (latest)

tropic pelican
#

I'm trying to get Cookies work with my new Angular 17 project. I have a route like /person/1/edit and it is protected with a guard like this:

export function authenticationGuard(): CanActivateFn {
    return () => {
        const authService: AuthService = inject(AuthService);
        const router: Router = inject(Router);
        const cookieService: SsrCookieService = inject(SsrCookieService);

        return authService.getUser().pipe(
            map((x) => {
                const bearerToken = cookieService.get('access_token');
                console.log('Bearer Token: ' + bearerToken);
                if (x.role !== 'admin') {
                    router.navigate(['/home']);
                    return false;
                }
                return true;
            })
        );
    };
}

When I directly open the route /person/1/edit in the browser I'm redirected to /home because the cookie is not set (e.g. the bearer token is empty).

I installed ngx-cookie-service-ssr and setup the part of the server.ts like similar to the documentation of the cookie ssr package:

server.get('*', (req, res, next) => {
    const { protocol, originalUrl, baseUrl, headers } = req;

    commonEngine
      .render({
        bootstrap,
        documentFilePath: indexHtml,
        url: `${protocol}://${headers.host}${originalUrl}`,
        publicPath: browserDistFolder,
        providers: [
          { provide: APP_BASE_HREF, useValue: baseUrl },
          { provide: 'REQUEST', useValue: req },
          { provide: 'RESPONSE', useValue: res },
        ],
      })
      .then((html) => res.send(html))
      .catch((err) => next(err));
  });

Sadly this does not work and the cookie is always empty on the server side even though I have a cookie in the frontend. Has anyone an idea what I could be doing wrong?
Maybe the server.ts part is wrong because the docs still have examples on how to do it with angular universal instead of the new Angular 17 SSR.

mossy pasture
tropic pelican
#

Thank you 🙂

tropic pelican
#

Hmmm, I thought it worked but that was only because of an error in one API. After I fixed that I get redirected to my home page again.

tropic pelican
#

I added some logging to the server.ts and in the request the cookies are available. But when a page is rendered/my guard is hit the cookie service is not able to access the cookie from the request even though I set the injection token 'REQUEST' to req. Super weird... not really sure why request still doesn't seem to be available to ngx-cookie-service-ssr

gaunt ruin
#

The two tokens aren't accessible with the devServer

#

(the devServer doesn't rely on server.ts)

mossy pasture
#

@gaunt ruin That's what the linked issue is about. But reading (quickly) the code of this library, I don't even know how it can work: it uses a non-exported injection token REQUEST here: https://github.com/stevermeister/ngx-cookie-service/blob/72b91d3b7bf228b0e338fbb52d2aea58323a3be9/projects/ngx-cookie-service-ssr/src/lib/ssr-cookie.service.ts#L18, and the documentation says that the server.ts should provide the request under the string token 'REQUEST': https://github.com/stevermeister/ngx-cookie-service/blob/master/README.md?plain=1#L140.

gaunt ruin
#

Yup, you're right

mossy pasture
#

So, @tropic pelican , you should open an issue on ngx-cookie-service.

tropic pelican
dusk igloo
#

@tropic pelican have you fixed the problem?

odd matrix
# mossy pasture <@172439969535754240> That's what the linked issue is about. But reading (quickl...

(Angular v16)

Looks like it is working there. For me, im getting the Request Header in my server side and can read all cookies from it with ngx-cookie-service-ssr.

Provide says:

/**
* An injection token. (Typically an instance of `Type` or `InjectionToken`, but can be `any`).
*/
provide: any;

so i think InjectionToken's are just the safe way of having tokens so you don't get typo problems with injections. Maybe Angular changed this for v17 how it is handled

dusk igloo
#

Can you share complete code?

odd matrix
# dusk igloo Can you share complete code?

For Angular v16 (will not work in v17) it is:

server.get('*', (req: any, res: any) => {
        res.render(indexHtml, {
            req,
            providers: [
                { provide: APP_BASE_HREF, useValue: req.baseUrl },
                { provide: 'REQUEST', useValue: req },
                { provide: 'RESPONSE', useValue: res }
            ]
        });
    });

in server.ts and then adding ONLY ngx-cookie-service-ssr and use SsrCookieService everywhere

#

Thats it basicly

dusk igloo
#

Any idea why in Angular 17 SSR isn't working?

odd matrix
#

I mean't the server.ts i've send will not work in v17 since v17 uses ssr and v16 is using universal for that. They have changed alot there i think

#

Still waiting for another lib to update to v17 so i'm not into that right now.

dusk igloo
#

We will have to wait for a fix in Angular 17 then...

tropic pelican
#

@dusk igloo sorry for the late reply but yes I got it working. I copied the SsrCookieService from the Github Repo, inserted in my Angular project and exported the REQUEST like this on the top of the SsrCookieService.

export const REQUEST = new InjectionToken<Request>('REQUEST');

and after that you can import this REQUEST in your server.ts.

After that it worked without any problems.

thorn urchin
#

this worked for you when debugging locally?

proven oak
#

@tropic pelican Hi I also have the same problem. I will only be able to test your solution on Monday. So if I understand correctly, no need to install the package, right?