401 Unauthorized - Chrome App Oauth to invoke Google Cloud Functions - oauth

I'm following this: https://developer.chrome.com/apps/tut_oauth
But it doesn't work. When I invoke Cloud Function, I get 401 error. The Authorization: Bearer "access-token" is added in the request header. Although another question here[1] states that ID_TOKEN should be used. Which I tried via curl but have the same 401 error.
chrome.identity.getAuthToken({interactive: true}, function(token) {
var dat = {
"user_email":email_id,
"user_id":user_id
};
$.ajax({
type: "POST",
data:dat,
dataType: 'json',
url:str,
contentType: "application/json",
error: function (xhr, status, error) {
console.log(xhr)
}, success: function (data, status, xhr) {
console.log('Success!' +data + status);
},
headers:{
'x-goog-project-id': 'xxxxxxxxxxxxx',
'Authorization': 'Bearer ' + token,
'Content-Type':'application/json',
'Accept': 'application/json'
}
});
});
[1] Why doesn't granting 'allAuthenticatedUsers' member the 'Cloud Functions Invoker' role work for google cloud functions?

The tutorial that you mentioned used "access-token" to accesses a user's Google contacts using the Google People API and the Chrome Identity API.
If you want to access a Google Cloud Function which does not Allow unauthenticated invocations you have to use an ID_TOKEN.
For testing you can create a service account with --role="roles/cloudfunctions.invoker", then create a key.json file and export the GOOGLE_APPLICATION_CREDENTIALS env variable link
Finaly you can use:
curl "https://us-central1-your-project.cloudfunctions.net/yourfunction"
# Error 403 (Forbidden)
curl "https://us-central1-your-project.cloudfunctions.net/yourfunction" -H "Authorization: bearer $(gcloud auth print-identity-token)"
#Success

I gave up on this as there is no direct solution to invoke Cloud function using oauth in Chrome Apps. The alternative solution that worked is to authenticate via API key. That is using Cloud Function with Cloud Endpoints.
I followed the logic here: https://medium.com/#akash.mahale/triggering-google-cloud-functions-with-cloud-endpoints-and-api-key-857e94a8a3aa
But just need to take note that rotation of API keys should be done regularly and automatically..

Related

Server's location is being sent instead of user's location

I have the following stack:
Rails API (backend)
Next.js (frontend)
In my Rails API, I am tracking where the request is coming from such as ip, user_agent, city, country, latitude, and longitude.
But the problem is that, instead of the user's data, it's the server's data that is being sent.
In my Next.js app, I use https://nextjs.org/docs/api-routes/introduction, since the access_token for the API is stored in the session. And I don't want to expose it to the client.
So the process would be, from React, I will make a POST request to /api/process/ of Next.js API endpoint. Then in /api/process I will take the access_token from the session and make a request to Rails API.
Since the Next.js API endpoint is the one made the request to Rails API. My Rails API stores the location of the frontend server instead of the actual user's info.
Pseudocode:
In React Frontend:
fetch('/api/process', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({ some: 'data' })
})
In pages/api/process.js:
export default function handler(req, res) {
fetch(RAILS_API_ENDPOINT, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${req.session.token}` // attach token here
},
body: req.body
})
}
Is there any workaround for this? I don't seem to want to expose the access_token in the client and make the request there to the Rails API directly.
You've set up a proxy API, as a result the Rails server knows nothing about the FE client because theres a layer in between. So there are 2 options:
Set up the FE client to call rails directly (which you said you don't want to do).
Forward this FE client information as part of either headers or in the payload to the rails API. From there the Rails API can then do whatever it wants with this data.

How do I initialise Swagger Client for the browser with an auth token?

In a browser-based (Cordova) app, I am trying to configure a swagger-client for the Strava REST API, to use an existing auth token in the request header.
Following the little guidance there is at
https://github.com/swagger-api/swagger-js/blob/master/docs/MIGRATION_2_X.md I have come up with the following
window.stravaClient = new SwaggerClient("https://developers.strava.com/swagger/swagger.json",
{ authorizations: { Authorization: 'Bearer '+ authToken }})
But, I keep getting the error:
TypeError: undefined is not a function (near '...).then( function() {...')

Recieving 400 bad request when trying to exchange authorization code with oauth 2 tokens

I'm trying to connect to an rss api provider 'Inoreader' and I'm using react native. I am able to get the authorization code but when I submit a post request for exchanging with tokens, I get 400 bad request. The response text is undefined. I checked and all their parameters are matching with my app's. I have tried.
This is their documentation: https://www.inoreader.com/developers/oauth
fetch('https://www.inoreader.com/oauth2/token', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Host': 'www.inoreader.com',
'Content-length': '217',
'User-Agent': navigator.userAgent,
'Content-type': 'application/x-www-form-urlencoded'
},
body: JSON.stringify({
'code':`${this.state.auth_code}&redirect_uri=${this.state.gizmos}&client_id=${this.state.userId}&client_secret=${this.state.userKey}&scope=&grant_type=authorization_code`
})
})
.then((res) => {
this.setState({
userName: res.access_token
});
console.log(res.status);
});
I see three problems in your code
You have a fixed Content-length value (217) from the Inoreader example. This way, the server reads just 217 characters of the request and the rest is discarded if the request is longer.
The request Content-type is urlencoded, but you probably don't URL encode the values. You can use the [encodeURIComponent()][1] function to do it.
The /token endpoint requires you to send a client secret, but your application cannot keep it safe, so the secret can easily get compromised. As they write in the guide, the request should be done from a backend. Or you can ask them to support OAuth2 for native apps.

Getting CORS error when I am making Ajax request to /common/oauth2/v2.0/token

Getting CORS error when I am making Ajax request to https://login.microsoftonline.com/common/oauth2/v2.0/token from my application.
Below is the code sample that I am using:
var inputData = {
'grant_type': 'authorization_code',
'code': '<codeValue>',
'redirect_uri': '<returnUrl>',
'client_id': '<client_id>',
'client_secret': '<client_secret>'
};
$.ajax({
url: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
type: 'post',
contentType: 'application/x-www-form-urlencoded',
dataType: 'application/json',
data: inputData,
success: function (data, text) {
console.log(data.access_token);
},
error: function (data, status, error) {
console.log('failed');
}
});
Browser console is showing below error:
Cross-Origin Request Blocked:
The Same Origin Policy disallows reading the remote resource at https://login.microsoftonline.com/common/oauth2/v2.0/token. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
I would like to know how to get ride of CORS error.
You shouldn't use the Authorization Code Flow to do client-size authentication. It would require that you provide the Client Secret as you're doing here and that is a big no-no.
If you need to handle authentication entirely on the client-size, you need to use the Implicit Flow (aka Client-Side Flow). This allows you to authenticate without passing a client secret and doesn't use a second-stage POST to obtain the token.
I wrote a walk through for how Implicit works that you might find helpful as well: v2 Endpoint and Implicit Grant

Twitter Api Request Token Url Issues

I need help with twitter API. request_token results in an error:
Could Not Authendicate You... Authorization Required.
My code is:
var url="https://api.twitter.com/oauth/request_token?";
url+="&oauth_callback=" +callbackUrl;
$.ajax({
url:url,
type:'POST',
data: {},
async :true,
beforeSend:function(xhr){
xhr.setRequestHeader('Authorization','OAuth oauth_consumer_key="3lqppVjoq7snHzGkvlab7uSix ", oauth_nonce="f7998b22bed5df683dc2f54c0a0679b3 ", oauth_signature="0CSKKi1hy901Mh6uHdLnL%2FDUXwE%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp= "1458408374 ", oauth_token, "403211404-jJsPD74gOelV7wFcSfoaRwfWAnZqsB9ysXDTO5ox", oauth_version="1.0"');
},
success: function(data){
alert(data);
},
error:function(error){
alert(JSON.stringify(error));
}
});
There are a couple of things I can immediately see:
The Twitter docs state that you should include all oauth_* parameters in the header if you are using HTTP-header based OAuth (this includes the oauth_callback parameter).
The oauth_token parameter is not part of the initial request token flow (because you haven't obtained a token yet) and so should be removed from the Authorization header.
Obviously check that your signature is correct which you can do with an online signature generator such as this one.

Resources