what can we do with instagram's access token? - node.js

I started working with instagram APIs using node.js and walked through the official instagram API docs here but it does not explain clearly.
Here I have 2 questions:
what is the difference between Client ID and Client Secret?
what is access_token ? and what is it used for ? and
when we should request for it ?

The client ID is is basically a unique id assigned to your application by an Oauth provider. It considered public information, and is used to build login URLs, or included in Javascript source code on a page.
An app requesting an access token has to know the client secret in order to gain the token. This prevents malicious apps from ever obtaining a valid access token. The client secret id doesn't state anything about authenticating a user, but it's instead for authorising an app to request access tokens.
The client secret must be kept confidential. If a deployed app cannot keep the secret confidential, such as single-page Javascript apps or native apps, then the secret is not used.
When you login with an Oauth provider, the server responds with an access token and expiration time in ms if the login is successful.
{
"access_token":"RsT5OjbzRn430zqMLgV3Ia",
"expires_in":3600
}
Every time client requests a resource from the server, the server validates the access code. The access-token is used to verify every request from the client. You will request for an access_token whenever you login through an Oauth provider.
You can refer this and this for more information.

Related

Securing a web app against authorization API without revealing credentials

I have a web app MyWebApp.
And two APIs: MyAuthAPI and MyServiceAPI, both RESTful NodeJS. MyAuthAPI uses HashiCorp Vault as a token store with OAuth2.
MyServiceAPI has CRUD operations available to authenticated clients.
There is no human login required (or desired) on MyWebApp. Any human can access MyWebApp through a browser and run the service.
At present, this is the (very insecure) flow:
MyWebApp sends clientid and clientsecret to MyAuthAPI to retrieve token. This token is then used for communicating with MyServiceAPI.
The obvious downside is that anyone can capture the clientid and clientsecret by simply looking in developer tools in a web browser. They could then use those to authenticate with MyAuthAPI, generate their own token, and make calls to MyServiceAPI without MyWebApp being involved.
So how do I best secure the entire application so that MyWebApp is safely and robustly authenticated without revealing the credentials?
Thanks.
ETA:
I want to be able to authenticate MyWebApp with MyAuthAPI and then use the generated token to connect to MyServiceAPI. But I don't want it to be possible that anyone can intercept those credentials - currently they can be see in the request header as "Authorization: Basic "
The MyServiceAPI endpoints must be secured so that only authenticated clients are able to access them. But when that client (MyWebApp) is a public website, how do I authenticate without making the credentials visible?
ETA2:
https://mywebapp.com is MyWebApp which is a React application.
https://myauthapi.com hosts MyAuthAPI
https://myserviceapi.com hosts MyServiceAPI
When I load mywebapp.com in a web browser, it authenticates with myauthapi.com/oauth/token to get a token. At present it does this by sending the creds in the header Authorization: Basic
The token that is returned is then saved.
The web application then tries to get the data from an endpoint on MyServiceApi using this token:
Authorization: Bearer
GET https://myserviceapi.com/objects
or POST myserviceapi.com/objects
or GET myserviceapi.com/objects/objectid
or DELETE myserviceapi.com/objects/objectid
MyServiceAPI verifies the token with MyAuthAPI, but that isn't public-facing, so there's no issue there.
The issue is that, as you can see from the attached screenshot of the Developer Tools console in Chrome, anyone using the web application can see the Authorization header containing the credentials, and could then use these credentials to programatically gain access to the auth API to generate a token which can then be used on the service API endpoints.
I want to restrict all access to the API servers to only come from specific applications, such as MyWebApp, on mywebapp.com.
First, I think this question could better be asked in https://softwareengineering.stackexchange.com/.
Second, where MyWebApp is deployed? How it is being used? If it works with https, then the body is encrypted, and when you send the clientId and clientSecret, you should send it in the body, so users will not be able to see them.
Client Credentials Grant should only be used by confidential Clients. Thats because you can't hide the client_secret on non confidential Clients. Your frontend seems to be a non confidential Client.
Normally you should use the Authorization Code Grant with PKCE. But you would need users to authenticate themselves for that.
Feels like you need an architecture design based on standard flows, since OAuth should work like this:
Web app signs user in via an Authorization Server, using Authorization Code Flow (PKCE)
Web app gets tokens from the Authorization Server
Web app calls API with an access token
API validates token using data from the Authorization Server
API then trusts claims in the access token and uses them for authorization
See my Initial HTTP Messages blog post for an example of how this looks.

SPA + API + OIDC: How to authenticate an API caller when it's only providing an ACCESS token?

Let's say you are developing a client side JavaScript SPA app (Angular), a backend API for this app (ASP.NET Core in my case) and you use an identity provider that implements Open ID Connect protocol (I'm using IdentityServer4).
Apparently the recommended way for securing the app is to use the OIDC implicit flow between the JavaScript app and the identity provider and if successful the JavaScript app gets an id token and an access token.
Now according to this documentation the JavaScript app is supposed to pass the access token in the headers whenever it calls the API. And I'm not sure what purpose does the id token serve in this case (besides customizing the UI in your JavaScript app)?
But this is the confusing part: The documentation also says you should never use the access token for authentication. But that is the token that my API receives in the request headers, how can it authenticate the user then? If my API receives Post(newRecord), and the API needs to internally fix some audit information on newRecord (i.e newRecord.CreatedBy = CurrentUsername), how can it do that without authenticating the caller??
I think I'm missing a piece of the puzzle. Please any help is deeply appreciated.
Short answer/suggestion
Use Access Token to access API endpoints. From API endpoints, you must use token introspection endpoint to validate token validity (active state) as well as obtain subject who authenticated at authorization server. IdentityServer provide support for this. Documentation is available from here.
Explanation
ID token is intended to be used by receiving client. It will allow your client to authenticate the end user and provide user specific customizations. This is the whole purpose of OpenID Connect (OIDC). On the other hand OAuth 2.0 provide an authorization framework. It replaces user credentials with access tokens, thus improving API access security (compared to basic authentication and storing user credentials everywhere). Hence OIDC is built on top of OAuth 2.0, you get both ID Token and Access token with OIDC flow.
But as you have figured out (and mentioned before), ID token is intended for client. There are could be exceptional cases where ID token get passed between client and a server. This is mainly when both are controlled by same party. But the access token is the key to access API endpoints, correctly.
Access tokens can be an opaque string or JWT. When it's a JWT, API can read and understand the token (self-contained). When it's opaque, only way to validate token at API endpoint is to use token introspection endpoint. If API can validate token validity, then it could grant access (authorize) request. Furthermore, if user details (subject) are available (through JWT or as introspection response), then user specific checks can be executed. This further extends to token scope values. But at the end of the day, you are authorizing the API request and not authenticating the user at API endpoint. That's the highlight. Hope things are clear now.!

REST api authentication using firebase admin sdk

I have a REST api and the authentication is done using jwt tokens. To make may api more secure (users and authentication mechanism) I would like to use firebase authentication. I would like to know can we use firebase as a authentication server for my REST APIs.
My understanding is that the client app will send the username and password to the firebase server and they will provide a token. Using that token client app will send an api call to our server. I need to integrate firebase admin SDK in my server and validate the token using admin SDK to get the data from my database.
Please correct me when I am wrong.
Also, i have a concern that how to manage refresh tokens to keep my app logged in.
Please help me to integrate this in the right way, and I am using nodejs/expressjs to create the APIs.
can we use firebase as a authentication server for my REST APIs.
Yes, it's one of the services they provide: https://firebase.google.com/products/auth/
My understanding is that the client app will send the username and password to the firebase server and they will provide a token.
Correct. The usual Firebase auth is done entirely client side.
But if there is a specific auth mechanism you need such as LDAP/AD or some other form of enterprise shenanigans, then you would need to create your own tokens that the client will use to authenticate: https://firebase.google.com/docs/auth/admin/create-custom-tokens
Using that token client app will send an api call to our server.
Correct. Once the client has successfully logged in and retrieved their ID tokens, you on the server side need to verify the ID token: https://firebase.google.com/docs/auth/admin/verify-id-tokens via middleware.
Also, i have a concern that how to manage refresh tokens to keep my app logged in.
You need not worry about that so long as the client uses the appropriate method to retrieve the ID token. For example, on the Web side the client would call: https://firebase.google.com/docs/reference/js/firebase.User#getIdToken which states (emphasis mine):
Returns the current token if it has not expired, otherwise this will refresh the token and return a new one.
As you can see, the client side Firebase SDK handles everything for you. There is no need for you on the server side to keep track of ID tokens, refresh tokens, or anything really. All you need to do is verify the token, that's it.
Please see my previous answer for more details on server side verification: Firebase authentication using NodeJS

OpenID Connect - should the id token be sent to the protected resource in this case?

Lets say I have a web API that a native application needs to make requests to. This API needs to authenticate who the user is that's making these requests via the native app. OpenID Connect seems to be the right choice since it is about authentication rather than authorization with OAuth.
The native app sends the users credentials to the IDP and gets back an access token (for authorization) and an id token (for authentication). From what I understand of OIDC, the access token would be sent to the API but the id token is only for the native client app. That doesn't make sense to me because it's the API that cares about who the user is, not the native app.
So why isn't the id token also passed to the protected resource (aka the API)? If you don't pass the id token to the API, what guarantees that the access token is secure and can be used to authenticate the user? Otherwise it would seem to lose the benefit of using OIDC over OAuth.
The OIDC Specification is designed in a way that ID tokens are always for Clients (Native app) and Access tokens are for resources (APIs). The ID tokens are always JWT tokens, but the Access tokens can be of different type.
The purpose of Access token is not to authenticate but to Authorize (Delegated Authorization). If, for some reason, the resource server wanted to know about the user, it can call the user-info endpoint.
The security/validity of token exchange can be validated in several ways:
Using encryption/signature with Public/Private key model where Authorization server encrypts / signs the access token with its private key and resource server decrypts / verifies with the public key.
Using token introspection endpoint to validate the claims, validity of the token etc..
Other attributes like AUD , AZP help in validating the issued access tokens.
Some OIDC providers use ID_Tokens to access API's - this is different to the model suggested by OIDC specification
This article has detailed explanation about these scenarios.

Should my app issue it's own access tokens, when using external oauth2 provider (facebook)?

I would like to give the users a possibility to login with some external oauth2 provider (facebook) in my app. The client's part is running on mobile device in a native app.
I am not sure which of the approaches below should I prefer ?
Should the client send the user's access token by facebook with each request ? At each request backend asks facebook to validate the access token. Based on the validation's result, backend performs authorization and return corresponding result to the client.
Should the backend ask facebook to validate the access token only at user logon, then issue its own access token, return the access token back to the client and client will use this access token at making requests to the server to avoid contacting facebook at each request ?
I have read some questions about how to implement the auth with facebook and most of the devs are using B, but I haven't seen any explanation why is it good/bad to use A ?
What I see as benefits of the solutions:
backend doesn't need to care about issuing, refreshing, validating access tokens since this is done only by facebook's authorization servers.
this solution seems to be more effective, since it does not require to connect to facebook at each request.
Security tokens issued by Facebook are signed with a digital signature. The API server only needs access to the public key to validate the signature. There's no need at all to contact Facebook after the user authenticates.
A reason to issue your own tokens after the user signed in with Facebook could be to add claims to the token. But obviously having your own authorization server comes at a cost. It's up to you to weigh the pros and cons.
If you do decide to have your own authorization server, make sure not to write your own! There are open source options like Thinktecture IdentityServer.
I will vote for option B and here is my explanation,
Your API must authorise the request every time with some auth token , which cannot be external provider token, in such case anyone with an access token (eg: other developers) of other provider can access your api, basically there is no auth here.
When your sever issue access token, it's easy to validate and when needed could be revoked easily (eg: on password reset)
While authenticating , your server has fully control over issuing access token , so the validation is made only once and doesn't have to do every time while calling the API.

Resources