I am Practicing on a Project and using Rails as a api backend and React as Front end framework. I have implemented Authentication in React but now how I am got stuck at the question of how to implement authorization.
We know in Rails we use cancancan or other gem for authorization which is session based but I cant use cancancan now because My whole front-end is in rails. Are there any ways of doing this work?
If all the permissions are at the backend part, some of requests must return 401 and your frontend part must respond accordingly (render a popup e.g, show a message).
If you are trying to hide some unavailable parts (menu items, buttons, pages) beforehand, your frontend part must get a list of user roles / permissions from the back beforehand and render page using this infromation. You can provide this along with authentication request or as a separate request.
I, personally, prefer pundit over cancancan
Related
I am planning to migrate some part of my website from Ruby to React while others still need to be supported on Ruby as Front-end.
But the main issue I am facing is concerned with Login Service.
In case of Ruby, after Login,cookie that gets generated is defined as
Rails.application.config.session_store :cookie_store, key: '_my_session'
So, even if I create a new login page using ReactJS ,I need to create a similar cookie(as I need to support some old pages on Ruby that use this cookie for authorization) after successful authentication.
So is there any way to create this 'my_session' from ReactJS ?Or How I can decode 'my_session' cookie?
It is possible to read and write that cookie without rails, but the implementation is specific to the version of rails you're using and the way your rails application is configured. But more importantly, that cookie is likely marked HTTP-only and in that case it isn't possible to read or write it from a client side app (not in React or anything other client side library). The login scenario is typically something you do on the server side and the server (Rails in your case), uses HTTP headers to read and write that session cookie. Set-Cookie to write to your user agent via HTTP response and Cookie when reading from the request sent by your user agent.
I have an API that I want to make a request to from my frontend, which is built using React. However, I don't want anyone to be able to see the API call in my code, because if someone just opens the inspect window, then they can see the API call. I've thought of perhaps adding some sort of header to be sent as authentication in the request, but that doesn't work either because you can just see the code if you inspect the site.
How would I do this? My API returns a private key that I can't just store in a variable directly within my code.
Sorry if this question doesn't make sense, but I appreciate all the help.
Your frontend code is insecure and observable by default. There is no secret in the frontend.
If your API returns confidential data that should only be accessed by the appropriate user you will have to implement authentication of any sort.
A user would then for example provide a password in order to call the API or he logged in before and got a token (e.g. JWT) that he sends with every request to authenticate. There is a user identity on every request then and your backend can decide if the user is allowed to get that private key.
If you really really want to make it difficult for someone to see your frontend code your router might provide a feature like "protected routes" that require such a token in order to access certain routes of your application. It will still always be possible to get the frontend code because the business logic has to stay on the backend.
Preamble / TL;DR
I've got a dumb API using the PassportJS JWT strategy that I'd like to add sessions to for the purpose of having user isolation in certain areas, a requirement for some enhancements.
The entire system is comprised of a MySQL DB, NodeJS + ExpressJS (with PassportJS) backend and an Angular 2 frontend.
Further Information
I've had an issue with implementing sessions in my application, and experienced the same issues as seen in this Github Issue.
My frontend doesn't seem to handle the session id stored in the session cookie with the key 'connect.sid', even though a user can be correctly authenticated initially and get their JWT. The session cookie does however get used when bypassing the frontend and using POSTMAN to send the requests.
The primary symptoms of the issue I'm experiencing are:
The session cookie is not created when using the Angular2 frontend. Sending the requests using POSTMAN seem to have the cookies created.
The req.isAuthenticated() call is always false as a result (unless using POSTMAN)
I've now deduced it must be an issue with communication/handling of requests/responses between the front/backend.
I've spent the last couple days running through other issues like:
Ordering/checking use statements: here, here
Adding the respective headers to responses on the front and backend: here
And a couple others. I do however draw the following questions from this:
Question(s)
Is it even correct implementing sessions with a JWT strategy, knowing the two should be exclusive from one another?
If not, what would you recommend be done in this scenario?
I have 4 angular applications one is a landing app which asks user to login and has to redirect the user according to its type
to one of the other 3 applications. I am unable to figure how to should i achieve that.
Have the three apps running on different subdomains. Upon login backend send a redirect response, figuring out what type of user it is?
But this leads to cors Error. Also i am not sure whether the cookie which i am setting will be accessible in all the subdomains or not.
Is there a way out?
You can do a redirect, but it seems like an unnecessary step (and kind of convoluted for this type of application).
Instead of returning a redirect based on login, it seems more straightforward to just return the address you want to redirect to in the response. Trigger a lookup to determine which app you should be directing to (however you're doing that) and then return the address of the app in the response data. From within Angular, you can extract the address from within response.data in $http. (see angular docs). The nice thing here is you also keep routing control and knowledge of state within Angular itself.
As for the apps themselves--instead of a subdomain, you can simply put the apps into different folders on your domain. This deals with CORS and the cookie issue.
Otherwise, you'd need to set a CORS header. You would do this on whatever backend you're sending the requests to--there's usually some sort of library to make it easy, for example, Flask CORS for Flask. If you need to share cookies in this case, this StackOverflow answer discusses one way of doing it (using an intermediary domain).
Generate a security key for the user session with some TTL in an authentication table when you authenticate the user with your App1
Redirect the user to any other app in any domain with this security key where they can query the authentication table and verify the user.
Let these other applications work on their own (in the front end) and communicate with the back-end with the security key when necessary.
Lot of PHP frameworks has built-in support for this mechanism. My favorite is Silex.
I'm using Laravel 5 with AngularJS for a project, in a way so that Laravel is used as an API and the API routes are in Laravel, while the client side routes are in AngularJS (app.js).
Is it possible to use Laravel Middleware to protect AngularJS routes, so for example, I want it to use the RedirectIfAuthenticated Middleware on the angular login form page route so people can't go to that page if they are logged in, except normally as far as I know, the middleware is specified in the Laravel controller, which doesn't have logic for angular side routes - hence, the problem.
So the question is, can I use Middleware or do I have to make angular send a get request asking laravel if the user is logged in on every page? Wouldn't that be less secure?
What I ended up doing was making a client-side cookie on login in angular to keep track of whether the user is logged in or not for user experience purposes (hiding information, redirecting before the view is rendered), and using Laravel Middleware to protect API calls to make sure the user can't interact or get information from the API on the server and to keep it secure in case the user changes their cookie to lie about their login status.
Alternatively, you could also send a request to the server before each page loads instead of the cookie check, but that adds quite a bit more overhead, and isn't any more secure - as far as I know, since that API call to check if the user is logged in is just for UX purposes too and the javascript for that can be removed by a malicious user.