# Moving from @auth0/auth0-spa-js to @auth0/nextjs-auth0, stuck on RBAC

**URL:** <https://community.auth0.com/t/moving-from-auth0-auth0-spa-js-to-auth0-nextjs-auth0-stuck-on-rbac/95150>\
**Category:** Get Help\
**Tags:** nextjs\
**Created:** [November 26, 2022, 1:01am UTC](https://community.auth0.com/t/moving-from-auth0-auth0-spa-js-to-auth0-nextjs-auth0-stuck-on-rbac/95150 "2022-11-26T01:01:26Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![ggascoigne](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/ggascoigne/32/20593_2.png) [@ggascoigne](https://community.auth0.com/u/ggascoigne)\
**Post date:** [November 26, 2022, 1:01am UTC](https://community.auth0.com/t/moving-from-auth0-auth0-spa-js-to-auth0-nextjs-auth0-stuck-on-rbac/95150/1 "2022-11-26T01:01:27Z")

</div>

I have an app that uses @auth0/auth0-spa-js, gets an access token and based on roles in the token, dynamically adjusts the UI to render or skip various components. Note that this is generally at a component level and not at a route level, and I like it that way. This works very nicely, and in fact is based on an RBAC example that I found in the auth0 repo several years ago.

Now I know that @auth0/nextjs-auth0 uses an Authentication Code Grant that goes out of its way to disallow the token from reaching the client, and yes, I get that that’s more secure, fewer features is alway likely to be more secure, but it’s really inconvenient.

My question is, how do people generally architect things so that their client side code can make role based determinations at runtime. Do folk just add another api endpoint to retrieve the roles and manage it independently of auth0? That seems more error prone than just allowing the access token to get to the client. Just go all in on SSR and hydrate the roles up font?

I will say that so far the auth0 code has been much more time consuming to migrate to next.js than the whole rest of the app, not what I was either expecting or hoping for.

---

<div class="post-metadata">

**Author:** ![ggascoigne](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/ggascoigne/32/20593_2.png) [@ggascoigne](https://community.auth0.com/u/ggascoigne)\
**Post date:** [November 27, 2022, 6:08pm UTC](https://community.auth0.com/t/moving-from-auth0-auth0-spa-js-to-auth0-nextjs-auth0-stuck-on-rbac/95150/2 "2022-11-27T18:08:06Z")

</div>

As a quick follow up, I’ve got a working solution now. The docs for `@auth0/nextjs-auth0` are pretty terse, however the code is full of useful comments (thank you).

What I came up with is:

in `src/pages/api/auth/[auth0].ts`

```auto
import { handleAuth, handleLogin, handleProfile, Session } from '@auth0/nextjs-auth0';
import { NextApiRequest, NextApiResponse } from 'next';
import JwtDecode from 'jwt-decode'

const auth0Audience = process.env.AUTH0_AUDIENCE

export default handleAuth({
  async login(req, res) {
    try {
      await handleLogin(req, res, {
        // you have to set audience otherwise you don't get a decodable token
        // and you have to do it at login otherwise the wrong value gets cached
        authorizationParams: { audience: auth0Audience }
      });
    } catch (error: any) {
      res.status(error.status || 500).end(error.message);
    }
  },
  async profile(req, res) {
    try {
      await handleProfile(req, res, {
        refetch: true,
        afterRefetch: async (req: NextApiRequest, res: NextApiResponse, session: Session) => {
          const decodedToken: Record<string, any> | undefined = session.accessToken ? JwtDecode( session.accessToken) : undefined
          // extend the user profile object with the "interesting" parts of the auth token
          // in this case the roles array set by the auth0 rule
          // this continues to keep tokens out of the client, but exposes the appropriate
          // additional information for the UI to make rbac-like rendering choices.
          return {
            ...session,
            user: {
              ...session.user,
              ...decodedToken?.[auth0Audience!]
            }
          };
        }
      });
    } catch (error: any) {
      res.status(error.status || 500).end(error.message);
    }
  }
});

```

Hope that this saves someone else some time.

---

<div class="post-metadata">

**Author:** ![konrad.sopala](https://sea1.discourse-cdn.com/auth0/user_avatar/community.auth0.com/konrad.sopala/32/13516_2.png) [@konrad.sopala](https://community.auth0.com/u/konrad.sopala)\
**Post date:** [November 28, 2022, 9:25am UTC](https://community.auth0.com/t/moving-from-auth0-auth0-spa-js-to-auth0-nextjs-auth0-stuck-on-rbac/95150/3 "2022-11-28T09:25:21Z")

</div>

Thank you a lot for sharing it with the rest of community!

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/auth0/original/3X/b/5/b560f266932fcce5d57f09a6595bd50518cae3f3.jpeg) [@system](https://community.auth0.com/u/system)\
**Post date:** [December 12, 2022, 9:25am UTC](https://community.auth0.com/t/moving-from-auth0-auth0-spa-js-to-auth0-nextjs-auth0-stuck-on-rbac/95150/4 "2022-12-12T09:25:59Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
