[FIXED] RESTful Authorization in the UI

Issue

I have two applications, an API (built with Flask) and an HTML/JS UI.

The API handles both authentication and authorization. Authentication is already working fine using cookies. I have a problem with my authorization implementation.

In the UI, I would like to disable a specific her HTML input field if the user is authenticated but not authorized. She also wants the UI to know if the user is not authorized so she can disable the control. The user can see the value, but cannot update it. Currently the protected route already performs an authorization check and returns a 401 if the user is not authorized, but I would like the UI to be aware of the authorization level.

An application that contains both an API and a UI makes this easy. For example, in Rails with CanCan you can do: :update, @article %>. But I can’t do that because my application is two separate applications.

I can’t use g sessions for Flask because I’m using two separate applications. Is returning the response headers the best way to do this? Is there a convention for that? Basic authentication tokens only contain the token, not the authorization level, so they are only useful for authentication.

Solution

It all depends on what type of authorization logic you need. You’re going to want some JS objects, in the example below I created an Ability object whose constructor function takes three parameters: user, car, company.

var Ability = function(user, car, company){
  this.user = user;
  this.car = car;
  this.company = company;
}

Ability.prototype.canSellCar = function(){
  return this.user.id == car.userId;
}

Ability.prototype.canWorkForCompany = function(){
   this.user.skills.forEach(function(skill, index){
     if(this.company.soughtSkills.indexOf(skill) !== undefined){
       return true
     }
   }
   return false;
}

Then you can create a new instance of the Ability object and pass it in instances of a user, car, and company, like so

var bobs_abilities = new Ability(bob, truck, government)

Finally you can call the methods you defined your ability’s prototype.

if(bobs_abilities.canSellCar){
  // UPDATE THE DOM TO SHOW THE UI ELEMENT THAT CONTROLS CAR SELLING
}

Hopefully this is a good start for you. Your ability class might need to do additional steps like make api calls to your server to get more information, or you might need to pass parameters into the functions defined on the Ability prototype.

If you were doing this with angular you might make the function’s on the prototype into their own directives so that your html would look like

<div can-sell-car user={{bob}} car={{truck}} company={{government}}>
  //Stuff you want to show in here
</div>

Definitely check out https://egghead.io/ if you want to look into using angular

Answered By – Ben Fischer

Answer Checked By – Robin (Easybugfix Admin)

Leave a Reply

(*) Required, Your email will not be published