Authorization Code Flow, sending the code from a mobile app to a REST API - security

I'm building a mobile app (and possibly a website) that uses a REST API to handle all the logic.
That being said, the REST api itself should call a 3rd party REST API (the Spotify one) to handle the logic for the app/website.
So basically the user should sign in to my app/website using its Spotify account and my API should make calls to the Spotify Web Api to retrieve user data using its access token, and then send them back to the app/website.
Now I've spent quite some time studying Spotify guidelines about authentication here and it looks like the Authorization Code Flow should fit my use case.
I definitely need to call the /authorize endpoint to retrieve the code from my app since I need user interaction for that. After that, I do get back the **code** that I should exchange for an access_token and refresh_token.
But as I said, it's not the app itself the makes the calls to the Spotify API, but my API. So theoretically I should send the received code to my API and let him handled retrieving and refreshing the access_token and refresh_token.
So my question is if this makes sense? Is it ok to send the code from the app to my api?
Not sure if it's clear so I'll attach a diagram of what I'm intending of doing.
Also probably after receiving the code, I would send back my own token to the app to be used with each future request (somehow similar with what you would do when you handle authorization with Facebook or other socials)

Hmm - some assumptions below, but I would aim to use standard flows. Some solutions are not possible in a good way though.
BUSINESS SOLUTION
Are you trying to build an app that combines the user's Spotify data with your own data for the user?
ARCHITECTURE TO AIM FOR
Your own UIs and APIs should use tokens issued by you and not Spotify. Only use Spotify tokens when you need to access Spotify resources. This leads to simple and reliable code.
STANDARD OPTION 1
This is based on you being in control of data from multiple sources:
You should have your own login and token issuing system. UI first logs into your app, which enables it to call your API with a token.
When you want to access Spotify you need to redirect the user again. The user can then consent to you using Spotify resources in your app, after which your web / mobile UIs get a Spotify token and can call Spotify APIs.
STANDARD OPTION 2
This is based on allowing the user to sign in with a familiar credential, which works via a federated login:
User needs to login
Your app redirects to your Authorization Server
There is a second redirect to Spotify
User logs in at Spotify
Spotify posts a token to your Authorization Server
Your Authorization Server posts its own token to your mobile app
Meanwhile your Web API has its own connection to Spotify that uses the Client Credentials Flow.
DOUBLE HOPPING CODES / TOKENS
This is not insecure, but it will add a lot of complexity and is not standard. You would need to maintain some kind of API session with 2 types of token per user and access token expiry would be a horrible area.
MOBILE FLOW
For mobile apps you should use Authorization Code Flow (PKCE) - my blog posts have some stuff on messages and user experience.

Related

Should I make 3rd party API calls in backend or frontend?

I have an API and that API needs some data from the Microsft Graph API. I was thinking of implementing an endpoint in my API to refresh the token and use that token to make calls from the frontend. I don't know if that's optimal or safe, hence my question.
EDIT 1: To give a better perspective of what I have, this is the logic I have at the moment. Tell me if this is correct please.
User requests my API's authorization endpoint, which has the Azure's secret key, then the user is redirected to the Microsft oAuth login page. Once logged in oAuth, Microsoft redirects the user to my API, where it saves the JWT tokens in the user's cookies, so the user can refresh the token anytime.
In order to refresh the token, the user simply just makes a call to myapi.com/auth/microsoft/token, where it has the secret key, and it refreshes.
Generally I would recommend always making the 3rd party calls from the back end. It gives you more control and avoids any cross origin complications.
You also want to be aware of any API keys. Most APIs require a key for access and often that key is private and you wouldn't want to share on the front end.
MS Azure APIs have an application and secret token. You cannot expose the secret token to the client. To call directly from the client you would use OAuth to get a JWT token and then you can call from the SPA into the MS Web APIs with that token.
https://learn.microsoft.com/en-us/azure/active-directory/develop/authentication-scenarios#single-page-application-spa
In contrast, there are other 3rd party APIs that are designed to be called only from the front-end. Stripe for example is a payment processing API where the UI can call directly into Stripe and then the client's payment information is never actually passed to the host application, only to Stripe. This improves security.

Secure Web API action without authentication

In asp.net web api, when you want to secure a action or REST endpoint, you use authentication, like token-based solutions. But, what if there is mobile app client for the api, and this have a sign up form, so I want only this mobile app could send Sign-Up request to my API, and prevent other fake clients (like POST-Man or a-alike) to send request to sign-up api?
Best
this is exactly the scenario covered by token based systems.
Your mobile app simply becomes a client with its own identifying data, then the API does its thing and only accepts requests from authenticated applications. This is exactly the kind of scenario you can cover with your own OAuth2 system.
Have a look at this article : https://eidand.com/2015/03/28/authorization-system-with-owin-web-api-json-web-tokens/
It will guarantee that only your mobile app can access that API.
Is this what you are after?

SPA ReactJS social registration with HelloJS and PassportJS

I'm facing a problem related to oauth authentication using NodeJS. The main concern is how to connect all to my current architecture. Lets me explain it a little bit.
I have a Cloud API which is a REST API to serve and manage the data. I also have the web client developed in ReactJS (an SPA). My main goal is to allow social authentication without redirect or without to leave the page. For this, I'm using HelloJS and the oauth proxy in the same Cloud API.
Taking for example my Facebook App, the workflow is like:
The user clicks signup with Facebook
The oauth proxy serve as "handshake".
Facebook sends back the token to the web app.
At this point, this approach is working perfectly for me. My main concern is how do I send the token to the Cloud API for registration?, obviously I could add a middleware in the Cloud API to automatically register the user in the database, however I still need to invoke the authentication from the web client in order to exchange that token for a JWT token.
Yes, I'm using JWT for communication with the REST API. I would like to allow local registration and social registration (Facebook, Twitter, and so forth).
It seems odd to me to trust in the token received from the web app without ensure that it is real and not expired. I thought to check it with passportjs.
Advices or recomendations?
Thanks.

Authentication strategy between my chome extension and server

I'm in the process of building a Google Chrome extension, and have some questions about how to implement security into the application.
I need to access a couple of Google API's so am going to be using OAuth 2.0 for that. So basically from the extension I know which user is logged into the browser.
My extension then needs to get and post data to my (nodejs) API service. I want to ensure that the user requesting data is the same user that is logged into the browser. Is there any way of using the previous Google authentication process to also authenticate communications between the extension and my API? I dont really want the user to have to log in again, to access my API.
I'm sure I'm missing something simple, and I've not been able to find anything that fits this scenario
Follow the OpenID Connect auth flow and you will get an access_token and an id_token. The acess_token you will use to use to make authenticated requests to Google APIs as usual. The id_token will be used as authentication with requests to your server.
When the requests hit your server you will need to validate the token and you can then use the contents of the id_token to identify the user.
User wouldn't have to login on auth process provided if user is already logged in and you are using a web application flow (not chrome.identity APIs) but user would see the consent screen atleast the first time. However you can skip the account selector screen if you already know the email address by providing &login_hint= parameter.

How to connect a Javascript front end using Facebook Login and a PHP back end through OAuth 2.0?

I have the following elements:
A PHP back-end providing a RESTful API secured with OAuth (FOSOAuthServerBundle with Symfony 2)
A Javascript front-end (AngularJS), i.e. an OAuth client.
My goal is to provide users with an authentification page in the front-end, allowing them to log in and access the API through the Javascript.
I do this the following way, according to this article: http://www.bubblecode.net/fr/2013/03/10/comprendre-oauth2/ (unfortunately in French, but if you scroll a bit, the diagrams explaining the standard grant flows are in English):
I provide a form asking the user credentials (login and password)
I use an OAuth Implicit Grant to exchange the user credentials for an access token.
Evertything should work (almost) well so far.
Now, the reason of this question is I want to add Facebook Login to my front-end. What this will give me is a Facebook access token each time a user registers with Facebook Login on my front-end. Ideally, my back-end should:
get this token
check it against Facebook PHP API in order to validate it
retrieve from Facebook PHP API the user Facebook UID
compare it to the ones of my app registered users
return an access token (this time for my own app, not Facebook) if and only if the Facebook UID matches with one of my registered app users.
My question is: which type of grant should I use to make the transaction between my front-end and my back-end in such a use case (given that it is of course not acceptable to give my Client Secret from a Javascript Client)?
Actually, I managed to found the solution. A custom grant should be designed to solve this problem, based on the Implicit Grant (in which the Client Secret is not asked).
However FOSOauthServerBundle does not yet implement grants based on public clients (see https://github.com/FriendsOfSymfony/FOSOAuthServerBundle/issues/266 for more details).

Resources