I am very new into this. Tried to get data from spotify. So tried the what they are provide but its not working. Getting bad request and in response its showing
{
"error": {
"status": 400,
"message": "Client credentials authentication not allowed"
}
}
URL : https://api.spotify.com/v1/me/following?type=artist (Get URL)
Provided Bearer token.
Also I want to understand that how can I pass user id here as if I need to get data for particular user.
Please help me on this.
From the docs (and messing around a bit), I found that the flow should look something like this:
Make a request to the /authorize endpoint with query params: cliend_id, redirect_uri, response_type and scopes (if you're just testing to get a token, use response_type: token)
You will be asked to log in and authorize the scopes (in this case it should be the scope allowing the client to read the user's artists)
In the redirect uri, there will be a token that you can use for the request
https://developer.spotify.com/documentation/general/guides/authorization/code-flow/
https://developer.spotify.com/documentation/general/guides/authorization/scopes/
Related
I followed MS auth flow procedure to get access token for my user
https://learn.microsoft.com/en-us/graph/auth-v2-user
I got the authorization code and use it to get the access token, now I'd like to know what organization this user relates to, so basically get the tenant ID. I did some research and found similar problem with the solution to parse the token with jwt.ms and get the information from the context of the token
How to get the organization (tenant) id from user profile using the Microsoft Graph API
However my token can't be parsed even though I can access API successfully with it, so what's wrong with the token and how I can get tenant information in this case.
EwB4A8l6BAAU6k7+XVQzkGyMv7VHB/h4cHbJYRAAAWz180lZTbJUbh6TAov+diYnFv/BAIuLw3WArAQXqP6G9ZUwSQUAyAmzwR7K5xCElA1vJMdAN/zyQ4WhG2Kf4PdztF5CrGsVL/Ne3KmAx8uu6NlmJsSCb3NlHWeJPc775Hepg7t/Twf0b/s//H8q5wS1uWI3cxo69v3Mrlxe7+9MCIyEuwl+2Zao/zO2puOwnmB3ATwi59P1t1UZuN9ABnnjW077/sdzhJztWYSUEAFkjMMibOhkGVe7kbNKqnW+aKJ5MgQ/J9jFxO+x30izhGZxRRKP4FQnW7LzI53CURXWoYF6E1EWBchrAdSeVjXU6gaacRGzenMMOWP9SbHSG3UDZgAACDrNVXGaAj+7SAJMl3SNFg0WntT4/e8Zq7wAL+41n+bRKhj6k4cs5MpCHoVdb+D4tteLULOS28dj119OlpU82YAYMMEz6HvrqisogGszHH28QZHIbYiKf3ql0mDypQoyaJFZ3s4J70PMHwLEiZQor9nE2cf2LNGRr+NRG6o5UxQx/eIkX3c2jrZmsuYaLMobTc2GriyTEtN2uznv0Ixfhe2B0lcFOHtgAyWfagyYySk3prQ06jGIe81mDvlaqzUwdN2+l6Tnc7ktZqgPvjFpCJzUe1yacYtCwU/T9sIqu7SKhNT0SLMq/GOK8VMAqJG30sRRSrl7FjUyL8CpeBZh6qKKkCXTOCA9WtkqtJrzDnQPYu3RvwGRdDnyJD3J5q72EflTn1JE+jqMbXe1oGYBMF1WObeUCuj3tX8aVzxD+JXqp+UlvdvyJbmwsge/cqWgzVbtOFk7SNSkVjaNoA2SnzprNuT9qeRsJovPyly6f+BdrfaBUxuGnq3b5FWD+TG4nbAyGWz6sk/ez5loUoJzivr0c4EYACOlqi9wfX7j/11goiM+UNxvtJ9eXCWY/ZvCO93GOrvXkgAhGFY5B7/bkLTQ4DjMJn4o13y/5HFfRF3NDVTvLR7m9eK891q4DihXu3JA0ZVlO27JS2MAwrxj5s4L2aAliPJU/IHnEXgr0Pih4UcRDjnfDVl3poz8nhjKUtoZgg7Ir059Vy76Nvb3x1XQRbsJy90emYJn5qMJB0+d9YNn/FFzuC7zWWl+8bUou8mP7f1kVEICdglwFDPqixGBJpwC
UPD
I'm on free personal MS account, the chain of calls looks like
https://login.microsoftonline.com/common/oauth2/v2.0/authorize
https://login.microsoftonline.com/common/oauth2/v2.0/token
teamsScope=offline_access,User.Read,Files.ReadWrite
{
"token_type":"Bearer",
"scope":"User.Read Files.ReadWrite profile",
"expires_in":3600,
"ext_expires_in":3600,
"access_token":"EwB4A8l6BAAU6k7+XVQzkGyMv7VHB/h4cHbJYRAAAR5OqwjPkutcuJ2gqMJgwv0Si4gZSYV978hSPi1z4vpbgXe4lUPNF0pR1BUY/8boa06hZnvyjhlDdMO5iNs/y0vzzXVo5AhrAogH89vxQ7k9m+G7aZpn0RsphyqyPQg27b1s8EVMaxJrDChr+zt8fTxcNnFMqXma1ycchAh6A1rZf4plTaKkHSU7q6x5zALw2JbXhKlIL+TVZFcLixzs84MP4Bc4OP/4Umhr18+lk9TkAO2jic26jkkcxJ5rl/NuKaw59dNqrfXFT51NsErdNM5AViTMjNUPSANhk1BGOLmVNUCCQkZu1KI0AdHVc+/9WjOI8Ie+ar8ib9vO8kFHlCMDZgAACPGA1GdE+yj+SAJCyS8jQBE88Phojtj+Mgjwtkaw6IByIWrTXTmEDowMRnYmgnr2FJvuHDRIlZaKnyYpJ4+BEeZBLp2Fw7BjDKCfgv2zPEIRXSZ8+VKO9BqpgfN1X3KlQrlqOO3tht6LL6Ji6t3vjJyhGocrpBQdwCeWaMBJzQkB4csMvXzyGLnJCIvY6IqMJMV/tvjJXcgrV3EJpMUoA63pPtu7d4YU2kaNMPnVRWTI2rXzSpS7Q4ztRRJadrUUOpxuOHjLECoLk1GtHHDlu1hfDNqRu9L/3rmIIz8TuoF38gwvj4hPTgXdjNh3zZDqvsK10jxj6a39u7eiy6poqvAP7G3JaBiVUGFcrA5kbcKXUT1eoQYNJGElOWOskWFBEO2h4w5d3zwu9wglFBhRhAH4YPd9d4k1LC7Jj5lxpOIGtfUNfcXjDDp2K1euuwOrhc5dW0WvUNR8Np0zSPwsrOhh9wASn4Ta2b3Z3Bn2c34jQmDxwMGGevU6a7SDDeE0QjIR0SN7kTro5cQawxJWf06JPayhK6Sx1SDMT3s1Mp5XXnB4tci2s+5MxxZ4NZduLKNJHh8+dojxHZ8KoSCYNa1NYUUAKZPG5Aao+NGAtD5uh3r58iFhAp2SHi6QH4TUyCMo1De8VXjSVS5fER8CPWBxldVrzxjMv1ffaSBphlT+ilxOJiL4IIKWkCdpru3c3J+eNrJ4N+873mLxYBRrGb+q7r4GkfdHhXyiR1eo0BD0aXOu1iBxsr7xLL00PE23quiXiV7s6GfL3ZKQ0h5jqWwcW5wC",
"refresh_token":"M.R3_BAY.CR9WAnqQDx9dzRd7Z7FrfDQMax0HCeVHW11xHOkMdnK3mGP4Pg!QcenTD3IKtJ0Tip948K!f93euTYcqyi8BOewY1ReYXRT4sOmHs!sR2290!*fez7m2xYXE8d3UHuuli2jWpXnbD*cg3l4HTpX90EoBzIg0U!soQnA5qRiHhMoBWqUnOm5Az6P6VplfNYTLnR1G0QF4yWpU4UJbDMe*kqsgf0h9dfQoyLLHYTXPnvZgkDIBlrYIAUOG7wglOFVLr!Rx9zCCvMCO13Irde*He5Uac2TKRxKHL5tzwSx1f4JlzYuEKOqt1iLOu9JHKV4SQ7zk!HjtPp4ZnxPzMPzuihFCOps*!20sm5Ux7ZARrt9OhIHicpun4uIz61VQrmXP!zqATVFohECSAh27zEZtIEDjAzSYkeAtVDzP75YnO2ARBjhNYCxbHyXww4WLhcA3CA$$"
}
This is related to your account type. If your account is a personal account, then your token is like this.
If you want to obtain a token in jwt format, you can add the personal account as a guest account to your Azure tenant. Then change /common to /tenant id.
I think you are doing something wrong. If you followed the guide, at some point you should have called POST /{tenant}/oauth2/v2.0/token which will give you an access token and a refresh token if offline access is enabled. The response would be something like:
{
"token_type": "Bearer",
"scope": "user.read%20Fmail.read",
"expires_in": 3600,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...",
"refresh_token": "AwABAAAAvPM1KaPlrEqdFSBzjqfTGAMxZGUTdM0t4B4..."
}
Having looked at your token, it is not a valid jwt and that is why jwt.ms wont decode it. Because Graph uses Json Web Tokens(JWT), You access token should be structured as header.payload.signature. You can get more familiar Graph API Tokens here
I am using FusionAuth for authentication. I have created one application in the FusionAuth. It has oAuth configured.
http://localhost:9011/oauth2/authorize?access_type=offline&prompt=consent&response_type=code&client_id=9ecc54b7-6f79-4105-a208-ca61e6157b58&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fipos%2Frest%2FfusionAuth%2FcallBack
This is my authorization url to one the FusionAuth login page.
Once I hit the link and enter the user name and password, I get the call back on configured call back url in my java jersey api.
I get the following details in the call back request.
code - dZgq5Xd0YmAQXZ2JIzkih832iojimgLUPwT7yoH9-TY
locale - en_US
userState - AuthenticatedNotRegistered
Here I am using Scribe Java library for OAuth authentication
I make call to get the access token call usnig the Scribe java libary with the given authorization code and grant_type is authorization_code.
Here this call get success and I get the below detail in the response.
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImRRZTA1Uk1vN19oVjZUUnpLVUQ1aXpRU2NSOCJ9.eyJhdWQiOiI5ZWNjNTRiNy02Zjc5LTQxMDUtYTIwOC1jYTYxZTYxNTdiNTgiLCJleHAiOjE1Nzc3MTg0NjgsImlhdCI6MTU3NzcxODM0OCwiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiI3ZWE3OWRhZi1hZjExLTQ1MTUtODljYS1iOGFjYTFjN2I5YTEiLCJhdXRoZW50aWNhdGlvblR5cGUiOiJQQVNTV09SRCIsImVtYWlsIjoiZGhhdmFsYmhvb3Q5M0BnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwicHJlZmVycmVkX3VzZXJuYW1lIjoiZGhhdmFsYmhvb3QifQ.eA0Xi6nEZhWaTMd-P26ESdE3NsyXNRNVBKBdBvHxvzfHgXYJiN2pf-16mY8JK-4-1g3vZF7Cwv-SkP4iZAIJCYYc3uBW8Qlcjjn9cyi7_RggBBBsErcs2acRIt-D5NpnVJfkxHwGAs9fO6a2Win98GGYyv1nzBG9OhWkyZJTy4QxzlgXNrkQIzTuzRwLkRFzKCT95pqfsOYb_MXPuAksg5q1SHIj8qtbO7EO-vMbpmiok1C-Wflbiq2X_tq17QBKbO4JAMLm9_pCZse1tqLyNP4fIh3VHTz7OdbbXvug2Tpk_yTWLVL_29XC87-91R5iXeezLjADkdi1yXMUdHioOw",
"expires_in": 119,
"token_type": "Bearer",
"userId": "7ea79daf-af11-4515-89ca-b8aca1c7b9a1"
}
Here, I do not get the refresh_token, in any case, user first time login or in any case.
This is JWT token and I had reduced the expiry time to 120 seconds.
In application OAuth setup I enable Generate refresh tokens option.
The only problem here I have is, I do not receive the refresh token.
Help me with this.
Thank you.
To obtain a Refresh Token as a result of the Authorization Code Grant, you'll need to request the offline_access scope.
https://fusionauth.io/docs/v1/tech/oauth/endpoints#authorization-code-grant-request
You can modify your request as follows (line breaks added for readability)
http://localhost:9011/oauth2/authorize?
scope=offline_access
&prompt=consent
&response_type=code
&client_id=9ecc54b7-6f79-4105-a208-ca61e6157b58
&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fipos%2Frest%2FfusionAuth%2FcallBack
As a side note, adding prompt=consent is fine, but it will not affect the request as this is not yet available in FusionAuth. Please upvote the feature request if this is something you'd like to see in an upcoming release. https://github.com/FusionAuth/fusionauth-issues/issues/411
We are trying to use Google OAuth in our product. The flow would be to get Client get the auth from the users and send the token to server. On server side I need to verify the token is valid. For now, I am using OAuth2Sample provided by Google as client. when I verify the sent token on server side, I am getting the following exception:
com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
{
"error" : "invalid_grant",
"error_description" : "Malformed auth code."
}
at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:105)
at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:287)
at com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest.execute(GoogleAuthorizationCodeTokenRequest.java:158)
Here is the code on the server side:
GoogleTokenResponse tokenResponse =
new GoogleAuthorizationCodeTokenRequest(
new NetHttpTransport(),
JacksonFactory.getDefaultInstance(),
"https://www.googleapis.com/oauth2/v4/token",
CLIENT_ID,
CLIENT_SECRET,
authToken, //Sent from the client
"") // specify an empty string if you do not have redirect URL
.execute();
Here is how I get the accesstoken on the client side:
private static final List<String> SCOPES = Arrays.asList(
"https://www.googleapis.com/auth/userinfo.profile",
"https://www.googleapis.com/auth/userinfo.email");
//...
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
httpTransport, JSON_FACTORY,
clientSecrets, //Client ID and Client Secret
SCOPES).setDataStoreFactory(
dataStoreFactory).build();
LocalServerReceiver lsr = new LocalServerReceiver();
Credential cr = new AuthorizationCodeInstalledApp(flow, lsr).authorize("user");
return cr.getAccessToken(); //send this to server for verification
The token is not corrupted on the way to server and it is:
ya29.Glx_BUjV_zIiDzq0oYMqoXkxz8VGzt8GCQuBiaaJ3FxN0qaLxbBXvnWXjNKZbpeu4jraoEqw6Mj9D7LpTx_8Ts_8TH0VGT5cbrooGcAOF0wKMc1DDEjm6p5m-MvtFA
If I try to access profile and email from the client side, it works fine. Same token does not work on the server side gets malformed token exception.
I am using Node.js googleapis client library, Here is my case:
The authorization code in the url hash fragment is encoded by encodeURIComponent api, so if you pass this code to request access token. It will throw an error:
{ "error": "invalid_grant", "error_description": "Malformed auth code." }
So I use decodeURIComponent to decode the authorization code.
decodeURIComponent('4%2F_QCXwy-PG5Ub_JTiL7ULaCVb6K-Jsv45c7TPqPsG2-sCPYMTseEtqHWcU_ynqWQJB3Vuw5Ad1etoWqNPBaGvGHY')
After decode, the authorization code is:
"4/_QCXwy-PG5Ub_JTiL7ULaCVb6K-Jsv45c7TPqPsG2-sCPYMTseEtqHWcU_ynqWQJB3Vuw5Ad1etoWqNPBaGvGHY"
In Java, maybe you can use URLDecoder.decode handle the code.
For anyone who might face this in the future. I faced this issue and decodeURIComponent did not work with me. The previous answers work with for different issue.
From the question itself, you can see that the token starts with ya29.
ya29.Glx_BUjV_zIiDzq0oYMqoXkxz8VGzt8GCQuBiaaJ3FxN0qaLxbBXvnWXjNKZbpeu4jraoEqw6Mj9D7LpTx_8Ts_8TH0VGT5cbrooGcAOF0wKMc1DDEjm6p5m-MvtFA
That indicates that the token is an online token. In case of the online login, you can see that the response looks like this
But that will not work with server side login. So, when using some Google client library, please note that there are two variables that you need to check:
access_type: offline
responseType: code
Once you configure Google client library with those fields, you can see that the response of the login will change to something like this
{
"code": "4/0AX4XfWgaJJc3bsUYZugm5-Y5lPu3muSfUqCrpY5KZoGEGAHuw0jrkg_xkD_RX-6bNUq-vA"
}
Then you can send that code to the backend and it will work.
Thanks to slideshowp2's answer, and Subhadeep Banerjee's comment.
I am using server-side web app with HTTP/REST ,also facing the same problem
and yes, the reason is that authorization code return from URL is encoded.
After decode, everything work fine to get access token.
p.s. here is some info about encodedURL
since our Content-Type: application/x-www-form-urlencoded
we do get this error when for some reason the call back url of the auth is called a second time. The first time it works but the second time it errors out.
Not sure how the users are able to do that. Maybe by pressing the back button in the browser.
The error is indeed this:
{"error": "invalid_grant","error_description": "Malformed auth code."}
Encoding the code in the call back URL was not the problem.
I get a valid code on the client side login of my application using angularJS Oauth Module GAuth.checkAuth(). and then GAuth.getToken().
The code is valid only for 1 hour and any API like GoogleDocs,Gmail accessed after 1 hour fails and needs relogin.
To overcome this I am trying to send the code to the server for getting AccessCode at Server so that I can send same with requests to GoogleDocs, Gmail etc
GoogleAuthorizationCodeTokenRequest req =
new GoogleAuthorizationCodeTokenRequest(
new NetHttpTransport(),
JacksonFactory.getDefaultInstance(),
"https://www.googleapis.com/oauth2/v4/token",
// "https://accounts.google.com/o/oauth2/token",
"901142925530-21ia7dqnsdsdsndnsnnnfdc9cm2u07.apps.googleusercontent.com",
"6NSvw0efghyuuG8YGOBWPln79n",
authCode,
"http://localhost:8080");
req.setGrantType("authorization_code");
//req.put("refresh_token", authCode);
//req.put("access_type", "offline");
GoogleTokenResponse tokenResponse =
req.execute();
tokenResponse.getAccessToken()
Where authCode is the code I received in GAuth Token
But the call is failing and in response I get
400 Bad Request
{
"error" : "invalid_grant",
"error_description" : "Incorrect token type."
}
Any help is highly appreciated!
When the user first authenticates your application you are given an authorization code. You then need to take this authorization code and exchange it for an access token and a refresh token. Once the authorization code has been used it can not be used again.
grant_type=authorization_code
Denotes that you are asking Google to verifiy that your authorization code and give you a new access token and refresh token.
It sound to me like you are taking either the access token returned from that request and sending it to grant_type=authorization_code end point which is not going to work its the wrong type of code. hens the error you are getting of
400 Bad Request { "error" : "invalid_grant", "error_description" : "Incorrect token type." }
You will need to take the refresh token you are given. If there is one I am not sure that you can even get a refresh token from AngularJs. You can get one using java though.
A refresh of an access token in pure rest will look like this
https://accounts.google.com/o/oauth2/token
client_id={ClientId}.apps.googleusercontent.com&client_secret={ClientSecret}&refresh_token=1/ffYmfI0sjR54Ft9oupubLzrJhD1hZS5tWQcyAvNECCA&grant_type=refresh_token
Note the &grant_type=refresh_token. If you are using the Google api java client library it should handle all of that for you. However your tagging is a little confusing its unclear if you are trying to do this in java or angularjs which I do not believe will allow you to use refresh tokens. Again I am not an angular dev I could be wrong on that point.
Anwser:
You the code you are sending is not an authorization code. Only an authorization code can be sent to grant_type=authorization_code. Solution: Send an authorization_code
Types of Google codes and tokens:
There are three types of codes or tokens you should be aware of with Oauth2.
Authorization code.
Refresh token
Access token
When you request access of a user and they grant your application access you are given an Authorization code. The Authorization code is short lived it probably less then 10 minutes and it can only be used once.
The Authorization code is used to get the initial access token and the refresh token from googles authentication server. by using the grant_type=authorization_code
Access token are good for about an hour. They are used to make calls to google APIs
https://www.googleapis.com/plus/v1/people/me?access_token={your access token}
You can use the access token as often as you want during that hour assuming you don't blow out some quota.
Refresh tokens are used to request a new access token from the Google authentication server when the access token you have current has expired or you just want a new one. here the grant_type=refresh_token is used to request a new access token you are essentially telling google I am sending you a refresh token you know what to do.
additional reading
I have a coupe of tutorials that might help you out Google 3 Legged OAuth2 Flow and Google Developer Console Oauth2 credentials
Also helpful when learning Oauth: The OAuth 2.0 Authorization Framework
I am new to the Facebook API. What I am trying to do without success is from my laptop create a new access token for myself through the Facebook API.
Below is the URL I am using to create this new access token:
String url = "
https://graph.facebook.com/oauth/authorize?client_id=##########&client_secret=##########&redirect_uri=http%3A%2F%2Fintelligentretrieval.com"
When I use my client id and then the client_secret (I assume this is the client password) then I get an error
{
"error": {
"message": "Missing redirect_uri parameter.",
"type": "OAuthException",
"code": 191
}
}
What exactly is the problem with this and the reason for the error?
Facebook requires a redirect_uri so I decided to dot it to my company site home page.(I figure this isn't the best place to redirect it but where should I redirect this?)
I want to redirect the result (generated access token) to my laptop from where I am making this URL request.
What exactly is the problem with this?
Is this possible with a browser like Chrome?
Is this possible using java?
Also is it possible to extend the access token expiration to 60 days with this url?
Please let me know if there is any confusion with any part of this post or if the answer can be found elsewhere.