I am using http://jsonapi.org as a the format for the responses of my api. I am however a little puzzled how to correctly respond to a request for an access token.
As far as I am aware, from the oAuth side I need to return the following:
{
"access_token": "abc1234...",
"token_type": "Bearer",
"expires_in": 3600
}
From the jsonapi docs I got that every request needs to return a resource object. And every resource object needs a data element with type and id.
However I feel this is not correct for the oAuth token request. Please help me how to do this correctly. Thanks.
I asked in the jsonapi forum and tyler kellen provided a very good answer (http://discuss.jsonapi.org/t/json-api-response-format-for-non-resource-data-like-oauth-token/74). I settled for this now:
{
"jsonapi": {
"version": "1.0"
},
"data": {
"id": "Qcg6yI1a5qCxXgKWtSAbZ2MIHFChHAq0Vc1Lo4TX",
"type": "token",
"attributes": {
"access_token": "Qcg6yI1a5qCxXgKWtSAbZ2MIHFChHAq0Vc1Lo4TX",
"token_type": "Bearer",
"expires_in": 3600
}
}
}
Related
Goal:
I have a simple web application where I submit my Blood Pressure and Heart Rate measurements.
Now I'd like to submit these measurements to my Google Fit Account.
I tried Googles tutorial: https://developers.google.com/fit/scenarios/write-bp-data
OAuth2 Setup
I created new credentials in one of my existing Cloud Console Projects. And then requested a new authorization code using the following scopes (The project is in Testing State and my account is registered as tester):
https://www.googleapis.com/auth/fitness.blood_pressure.write
https://www.googleapis.com/auth/fitness.heart_rate.write
Requesting the token returns the following response:
{
"access_token": "ya29.XXXXXXXXXXXXXXXX",
"expires_in": 3599,
"refresh_token": "1//XXXXXXXXXXXXXXXX",
"scope": "https://www.googleapis.com/auth/fitness.heart_rate.write https://www.googleapis.com/auth/fitness.blood_pressure.write",
"token_type": "Bearer"
}
As you can see, both write scopes are granted.
Additionally, if I check the permissions in my Google Account, both scopes are set.
Create dataSource
Now I create two dataSources (one for com.google.heart_rate.bpm and one for com.google.blood_pressure).
creating the Heart Rate dataSource works as expected, but creating a dataSource for Blood Pressure returns a 403 PERMISSION_DENIED Error:
Request (POST https://www.googleapis.com/fitness/v1/users/me/dataSources)
{
"dataStreamName": "BPA-BloodPressure",
"type": "raw",
"application": {
"detailsUrl": "https://aaa.bbb.ccc",
"name": "Blood Pressure App",
"version": "1"
},
"dataType": {
"name": "com.google.blood_pressure"
}
}
Response
{
"error": {
"code": 403,
"message": "Scope not included to modify data of type com.google.blood_pressure. Possible scopes: https://www.googleapis.com/auth/fitness.blood_pressure.write",
"errors": [
{
"message": "Scope not included to modify data of type com.google.blood_pressure. Possible scopes: https://www.googleapis.com/auth/fitness.blood_pressure.write",
"domain": "global",
"reason": "forbidden"
}
],
"status": "PERMISSION_DENIED"
}
}
The Google Fit REST API tells me that the Scope fitness.blood_pressure.write is missing, but as you can see the Scope is given for the used access token.
Notes
I am working with Postman to test all requests. Later a Java/Groovy or PHP backend will used.
I also tried with read and write scopes for both data types.
I can see my app with both write scopes in Google Fit under "Connected apps".
Change dataType name to "fitness.blood_pressure" instead of "com.google.blood_pressure"
The body will be like this.
{
"dataStreamName": "BPA-BloodPressure",
"type": "raw",
"application": {
"detailsUrl": "https://aaa.bbb.ccc",
"name": "Blood Pressure App",
"version": "1"
},
"dataType": {
"name": "fitness.blood_pressure"
}
}
API details:.Net Core 3.1 REST API using IdentityServer4 version 3.1.3
I have many APIs which send responses in a specified format.
For e.g. Register endpoint returns below response:
{
"responseCode": 0,
"developerMessage": "Response code not specified.",
"clientMessage": null,
"data": {"id":123},
"exception": null
}
I developed the authentication server using IdentityServer4.
But, my token endpoint returns below response:
{
"access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ik...",
"expires_in": 1209600,
"token_type": "Bearer",
"refresh_token": "1u8_VOFHTaeqWEWd6R...",
"scope": "offline_access api1"
}
Now the requirement is that all the endpoints of the API should return the response in the same format.
Which means I need to change the response of the token (or more) endpoints.
I looked into the ICustomTokenResponseGenerator service (mentioned here) but all it does is adding more fields to the response. And it is from IdentityServer3
class CustomTokenResponseGenerator : ICustomTokenResponseGenerator
{
public Task<TokenResponse> GenerateAsync(ValidatedTokenRequest request, TokenResponse response)
{
response.Custom.Add("custom_field", "custom data");
return Task.FromResult(response);
}
}
But, I want to completely change the response.
Is there any other service that I can use to get the below response?
{
"responseCode": 0,
"developerMessage": "Response code not specified.",
"clientMessage": null,
"data":
{
"access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ik...",
"expires_in": 1209600,
"token_type": "Bearer",
"refresh_token": "1u8_VOFHTaeqWEWd6R...",
"scope": "offline_access api1"
},
"exception": null
}
As explained in your GitHub ticket:
IdentityServer is an OAuth implementation - what you are suggesting would be incompatible with OAuth and thus is not supported by us.
If you need to change the complete payload to something custom - write some middleware to intercept the response.
When I try to send a GET request to Foursquare API below, I get "No matching endpoint." error.
I have validated my tokens and everything seems normal. Any advices?
REQUEST URL
https://api.foursquare.com/v2/users/USER_ID/tastes
RESPONSE MESSAGE
{
"meta": {
"code": 404,
"errorType": "endpoint_error",
"errorDetail": "No matching endpoint"
},
"notifications": [
{
"type": "notificationTray",
"item": {
"unreadCount": 0
}
}
],
"response": {}
}
FoursquareAPI twitter account has told me that I needed to pass m=foursquare in addition to version information.
The correct endpoint information is like
https://api.foursquare.com/v2/users/USER_ID/tastes?oauth_token=TOKEN&v=20150420&m=foursquare
The detailed information about v and m parameters are below.
https://developer.foursquare.com/overview/versioning
The title says it all. Is there an API call in the Google APIs which, when given an access_token or a refresh_token, returns the scopes that are granted to that token. I could not find anything about this question in Google's documentation.
Yes there is !
Just call this URL :
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=XXXXX
The result looks like this. You'll only get the email if you included an email-related scope in your token.
{
"issued_to": "407408718192.apps.googleusercontent.com",
"audience": "407408718192.apps.googleusercontent.com",
"user_id": "1170123456778279183758",
"scope": "https://www.googleapis.com/auth/userinfo.email",
"expires_in": 3585,
"email": "someone#yourdomain.com",
"verified_email": true,
"access_type": "offline"
}
More info on this blog post.
Shamelessly stolen from this ( https://groups.google.com/forum/#!topic/instagram-api-developers/tRfU444ZyhU ) thread as I have the exact same issue and hoping for better responses here.
Long story short, a few hours ago this was working, now it isn't.
The test platform can be found at both from my website and https://apigee.com/console/instagram
Sending https://api.instagram.com/v1/tags/türkiye/media/recent (careful with the "ü")
result: {
"meta": {
"error_type": "OAuthParameterException",
"code": 400,
"error_message": ""client_id" or "access_token" URL parameter missing. This OAuth request requires either a "client_id" or "access_token" URL parameter."
}
}
Sending https://api.instagram.com/v1/tags/turkiye/media/recent (now with "u")
result: {
"pagination": {},
"meta": {},
"data": [
{},
{},
{},
{},.. .. .. ... and so on
Sending https://api.instagram.com/v1/tags/türkiye/media/recent?client_id=7176aa6ef2fd47fd9cb373a5354bd30f ("ü" again and this time manually attached client_id)
result: {
"meta": {
"code": 200
},
"data": {
"media_count": 1471127,
"name": "t"
}
}
This time I'm getting the name as "t". It seems the query is broken just before the "ü" letter which is UTF-8 (Turkish if needed).
This is a bug on Instagram-side. There's an open discussion on Instagram Developers Google group. Although, from what I've seen in my application, the bug now resolve.