6

I already have a solid back-end permissions authorization (ie. admin can perform an action, a normal user cannot perform an action). However, I'm wondering if there is a better way to do a frontend authorization for my single page JavaScript application then fetching a permission from the API every view.

Seems like I could:

a. Have a global way to tell what kind of user it is?

  • I could do this but if permissions change in the backend I'd have to update who can view what on the front end.

b. Check permissions on every view?

  • Just seems like a lot of API requests

c. Create a separate app for a Dashboard?

  • That way I could know all the user's current permissions without a normal user getting back there looking around.

I may have answered my question with c but if anyone thinks of a better idea I'd like to hear it.

  • 3
    What do you mean with permissions? If some feature is admin-only, you shouldn't even let the user be able to trigger that method eg; hide the button. – JoeriShoeby Apr 23 '18 at 17:35
  • 2
    Get a JWT from the server with claims based info for the user: that JWT travels around with the requests and can be stored in local cache. Being claims based, you can have a claim saying the user is type of X, with application logic that renders Dashboard A or B depending if user is type X or Y, etc. – jleach Apr 23 '18 at 17:48
  • 1
    I agree with @JoeriShoeby, you need to clarify what you mean here. Permissions should be managed by the back end. The only thing that should be happening on the front end is tailoring the UI to only show options that the user has access to. Attempting to enforce permissions on the client is mostly pointless. – JimmyJames Apr 23 '18 at 19:53
  • I have 4 roles essentially; Admin, Data input user, Normal user, and guest. Because all the things that I really need is to protect the dashboard, I'm just wrapping the dashboard as its own JavaScript app and wrapping a few components that check for say admin permissions. And for the rest of the app, I'll just check if they are logged in or not. If I need to reach for something more sophisticated I can later, but either way my backend is already covered. Thanks for the disscussion. – Christian Pavilonis Apr 25 '18 at 16:45
4

It depends on what you mean by "permissions". I will present some ideas with an example with User and Project resources.

If the permissions are independent of a given Project, then you are really talking about the User having a role (e.g. admin). This can be encoded in the API representation of that User.

If the permissions are dependent on the underlying resource (e.g. a User can have different permissions for a given Project) these can reside in the API representation for that resource. This has the pro that you don't need a huge dictionary of all of a user's permissions and the con that any caching of that resource need to be user specific. This may be an acceptable trade off.

You still have a potential usability issue with stale data if someone loads a view and their permissions for the viewed resource change before they attempt an action. One way to try to mitigate this is to use websockets to push updates to viewed resources to try and reduce the window during which the UI will be out of date with the backend database.

  • 1
    This works. Refreshing automatically might not really be necessary if permissions are not expected to change frequently. Since authorization is managed at the server, there's no real risk of the UI displaying stale options. – JimmyJames Apr 23 '18 at 19:56
2

One approach would be to save all the user's permissions into local storage, build a wrapper around that and display/hide stuff base on what he or she can do.

  • 3
    this reads more like a comment, see How to Answer – gnat Apr 23 '18 at 15:18
  • The problem with this is that you can alter the data in local storage using browser dev tools. – Dr Blowhard Sep 18 '18 at 12:15
2

There are a many options to do that. I've used an approach that consists on:

  • Call API to get the authorization list when the page is loaded for the first time; Cache the results.
  • Before routing to a view call API that query the last update of user grants returning only the timestamp.
  • If there is change, call API to get the authorizations updated after the timestamp of the last change.
0

One solution is to generate an sign (as in asymmetric cryptography) an authorisation token on the server-side, since it's signed, it cannot be tampered with as an attacker doesn't know the private key.

i.e. You token might look something like:

id: userId
type: type of user
privileges: {
    privilege1,
    privilege2
}
expiry: some time in the near future, after which your app should request a new token

You would then sign this on the server, using a private key. The freely distributed public key allows anyone to verify that the server was the one who issued the token, and thus your javascript app can safely use the token to determine what the user has access to.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.