Search code examples
javascriptnode.jsreactjscasl

User Authorization with CASL library share between backend and frontend


I am looking at a way to implement authorization in both frontend(React) and backend(Node.js, Koa, GraphQL). I have stumbled across the casl package: https://github.com/stalniy/casl .

Though the backend authorization seems pretty straightforward to me, what I don't get is how can I share my authorization rules from the backend to my frontend. One medium post suggested JWT tokens. How would one go about doing that with a JWT token ?

https://medium.com/dailyjs/casl-and-cancan-permissions-sharing-between-ui-and-api-5f1fa8b4bec


Solution

  • It seems CASL has 2 function to achieve this, packRules and unpackRules.

    As per documentation in the backend you can do:

    import { packRules } from '@casl/ability/extra';
    import jwt from 'jsonwebtoken';
    import { defineRulesFor } from '../services/appAbility';
    
    app.post('/session', (req, res) => {
      const token = jwt.sign({
        id: req.user.id,
        rules: packRules(defineRulesFor(req.user))
      }, 'jwt secret', { expiresIn: '1d' });
    
      res.send({ token });
    });
    

    And in the frontend you do:

    import { unpackRules } from '@casl/ability/extra'
    import jwt from 'jsonwebtoken';
    import ability from '../services/appAbility';
    
    export default class LoginComponent {
      login(params) {
        return http.post('/session')
          .then((response) => {
            const token = jwt.decode(response.token);
            ability.update(unpackRules(token.rules))
          });
      }
    }
    

    https://stalniy.github.io/casl/v4/en/api/casl-ability-extra