Is it safe to have a frontend button that links directly to backend? - reactjs

I am creating a full stack application with a React/TS frontend and FastAPI Python backend both on different domains/origins. For my first API endpoint (an auth endpoint), I cannot use axios.get(/login) as I planned as I'm using a 3rd party API in my backend that doesn't work with redirects to my frontend. The solution seems to be to have a login button with an a tag that directly links to http://backend_url/login. This does work, but it feels weird/unsafe to literally send users on the frontend to the literal url of my backend as opposed to just calling HTTP requests to the backend. Is this bad practice? Is there a better way to accomplish this? I appreciate any direction.

The question is more on how to deal with a 3rd party API that a user needs to authorize, see comments on OP.
You can redirect directly from your frontend to the /authorize endpoint of Spotify. They will call the returnUrl that you gave when you registered your application with them, and provide a authorization code. If this is in your frontend (e.g. http://frontend.com/oauth/callback, that can take that authorization code and feeds it to your backend (for example, to http://backend/api/auth). That endpoint can exchange the authorization code for access tokens (calling the /token endpoint of Spotify, of something similar) using the client credentials that you received when you registered your application with Spotify. The backend can store and use those access tokens, and your frontend can call the backend.

Related

Secure an API using React with CAS (Single Sign On) for frontend and Spring Boot for backend/Rest API Calls

I'm working on a React frontend app, and believe I have CAS working correctly to secure the frontend using this package: https://www.npmjs.com/package/react-cas-client
Now I would like to secure my backend, and only allow the app to access the API calls, presumably using JWTs (or some form of token). All of the guides I'm finding, however, require the use of Spring Security, and passing the username/password to get the JWT. In this situation I'm using CAS, so I don't have a username/password to pass in.
Could anyone point me in the right direction? Thanks!
if your ui is decouple from the backend which i think it is based on your description, you can do this with proxy grant ticket, you can look the offical doc about how the proxy works. following are high level how you can do this with front end and backend decoupled:
After user entered right user credentials, cas will do 2 things, on ui your response contains a proxyGrantingTicket, and will send a callback to your backend with pgtId and pgtIou(this is proxyGrantingTicket you received on front end).
once you have both pgtId and pgtIou, you will use those information to do the authentication from now on.

How to allow only my SPA to call my public rest API?

I've a SPA (Angular based) published at my-example-domain.com and rest API (based on Laravel 5.3), exposed at my-example-domain.com/api.
All API are public, so unauthenticated user can use my Angular SPA and call backend API.
I would like to allow ONLY my SPA to call my backend rest API so, for example, nobody should be able to call my rest APIs through a rest client/curl.
How can I reach this goal?
What kind of authentication should I have to set up in my Laravel app?
Is Passport the right way?
You can't.
Your client is available to the public.
It runs in a browser, so all the HTTP requests it makes can be inspected by its users (i.e. everyone).
Anything you do to try to identify the request as coming from your client, can be inspected and replicated by anyone.

Securing a React frontend and with Python API using AWS Cognito

I'm considering using AWS Cognito as a user management system for a single page web app I'm building using React along with a Python REST API backend (Pyramid). I'm struggling to see how all the pieces fit together for my architecture (the docs don't seem to be helping me). There are many great examples of how to implement authentication into the frontend using JS. My issue is how to integrate this authentication into my backend REST API.
In my current hand rolled user management system, the frontend calls the REST API on sign-in and is given a token which is passed to API again for every subsequent request. I'm then able to use ACL's on my API functions, check permissions to access resources, etc. If I were to use Cognito and perform the authentication on the frontend (as many examples do) how will my backend know if the token is valid when it receives it with a request? Surely I wont have to call Coginto from the backend to verify this for every request? Also how can I perform checks for information such as 'is this user in the admin group' if that group is defined within Cognito? Again, calling out to Cognito for every request seems very heavyweight and cumbersome.
I did see one example where a list of valid tokens was exported from Cognito as a JSON file and kept on the backend. This seems horribly static when users could be added and removed regularly.
Is Cognito really suitable for my use case? Some high level guidance and pointers to any relevant examples and docs would be greatly appreciated!
When authenticating with Cognito, the user can have 3 tokens:
Refresh
Access
ID
For python, boto3 can interface now with Cognito. There's also this python lib wrapper: warrant, to make it easier.
Once you have the token, it is possible to pass it to the API (eg: access) and it can be checked on the server side with python-jose, as per AWS docs
To pass the token, an example pyramid /login implementation can keep the information in the session before setting the request response:
request.session['my_token'] = str(a_token)
The default cookie session factory works, though it warns that the token is not sent encrypted.

How to authenticate end users in an app having AngularJS UI and Spring Boot Rest Server with Spring Security

I have two apps.
Front end - AngularJS website running on localhost:9000 and getting data from rest service (database)
Back end - Spring Boot Rest Service localhost:8080
How to create authenticate process for this two app? Login from (user, password). I reading some tutorials on spring website, but front end are build in spring project on the /resouce folder, not separated.
There are a couple of things you need to keep in mind if you are setting up your app the way you want to.
What kind of authentication mechanism do you want? For rest services Basic and oAuth2 are most common.
With Basic auth you would send authorization header in each request.
Each request will perform authentication all over again.
There is no state between client and server
Https is mandatory if you use basic auth.
With oAuth2 first you need to send basic authentication request to end point your.app/oauth/token? --- parameters
Response will contain
access_token": "CQPt2VR2HJuCY3mb0xA1BVMyDltgvnpf6N2CXdsds3423YkGQID7VO-Mmu4idymlz"
Which you then include in every request with bearer token :
Authorization Bearer CQPt2VR2HJuCY3mb0xA1BVMyDltgvnpf6N2CXVPXkaewYkGQID7VO-Mmu4idymlz
access_token has an expiration time. You can also send refresh_token which has longer expiration time.
There is no state between client and server
For smaller applications oAuth2 is too complicated and basic will suffice.
This is just an overview of common authentication methods. There are a lot of implementation tutorials. Example : https://spring.io/guides/tutorials/spring-boot-oauth2/ and http://www.baeldung.com/rest-api-spring-oauth2-angularjs
One thing to keep in mind is you will need to setup CORS filter. If you run your service and client on different ports. For starters annotate methods you want to use with #CrossOrigin(origins = "http://localhost:9000") You can of course register global cors filter.

Oauth social login using MEAN.js Restful sessionless API backend

I'm developing a Restful API using MEAN.js, which will be consumed by an AngularJS Web site and Phonegap Mobile Apps.
I'd like the user to be able to create an account and/or login using Faceboo, Google and Twitter.
I'm trying to use the same sample code that comes with MEAN.js seed application, but with the Node side of it, on port 3000 serving only the API, and the web site running on another server (currently on port 9000).
I','ve already implemented Token authentication using a Passport custom Local strategy, which generates a token, and the Bearer Strategy to autheticate API calls.
But I'm having problems with social login, to link social accounts to existing users.
From the Angular Client I call an api endpoint that redirects the user to the oauth provider (e.g. Twitter). When the user comes back, my serve has no knowledge of the logged user, since I'm not using sessions anymore.
I've tried to return the provider token to the client, but have problems parsing the anguler url. Then I coded another page outside angular that receives the provider token and calls an api endpoint sending the oauth token and the token issued by my api. It worked for Google, but not for Twitter. It seems twitter needs a session.
Anyway, what is the best approach to achieve what I want? How can I make this work?
Since your using Angularjs, take a look at this Angularjs library https://github.com/sahat/satellizer. The library pretty much opens up an oauth popup and checks the popup url for tokens. You can easily replicate the approach or just use this library. It works with a few social media providers like Twitter and its easy to add more.
I was in need of the same thing and so I set out to create my own. It's still in development but should give you a good start. Feel free to create a pull request and help to make it better. Maybe we can eventually merge it into their codebase.
https://github.com/elliottross23/MeanJsSocialLoginTokenAuth

Resources