In order to use Discord's API I need a token, and to get it I open a link such as
https://discordapp.com/api/oauth2/authorize?client_id=<client_id>&redirect_uri=<redirect_url>&response_type=token&scope=identify
Then I set the token as authorization (in format Bearer <token>) header of requests that are issued to the Discord's API.
Let's say I want to "logout", so that a certain token can't be used anymore to do such requests. In this case I have to revoke that token, right?
So after reading Discord's documentation and making some adjustments I decided that I have to make a POST request to a URL such as
https://discordapp.com/api/oauth2/token/revoke, and content-type header of this request should be set to x-www-form-urlencoded.
When I do it I'm getting an error message from discord's server with message saying {error: "invalid_client"}
What do I do wrong?
If you come by this question and are wondering what is the full API call to revoke the token, here it is:
POST https://discord.com/api/oauth2/token/revoke
Content-Type: application/x-www-form-urlencoded
data:
client_id: <client_id>
client_secret: <client_secret>
token: <access_token>
So the problem was in actual format of the data I was sending. I was sending JSON data because I thought that setting specific headers would automatically turn the data into the right format, but it turns out I had to use FormData object to create the data in the right format, and after that I also removed the lines where I'm setting the header explicitly, after these steps everything worked fine.
Related
I have an api and i have gained access to the bearer token by sending username and password . I need to use the token to then send send another request using Oauth2 gem(ruby). H I have the endpoint
below is an example of something i think it may look like. I don't know the syntax or how to send this token to the url
it would be great if someone could give me an example of how to set up the method. Where to plug in the bearer token that i have saved to an instance variable, etc.
req = Net::HTTP::Get.new(url.to_s)
You need to add Authorization to the header, where the value is the bearer token. A header can be set like so req["header_name"] = header
You seem fairly new to this, I suggest you use RestClient instead https://github.com/rest-client/rest-client. Much more user friendly and the documentation is easier to read.
I'm having trouble to allow users to logout from an application that uses Keycloak for access management.
I have found this topic being discussed here and there, but not clear instructions on how to handle the logout.
I tried to cause the logout of an user redirecting the browser to an endpoint of the following format:
https://example.com/auth/realms/myrealm/protocol/openid-connect/logout?id_token_hint=mytoken&post_logout_redirect_uri=https://example.com/initialpage/
What I used as "mytoken" was the access_token I had obtained making a post request to the endpoint:
https://example.com/auth/realms/playipintern/protocol/openid-connect/token
passing to it parameters like the ones bellow:
grant_type="authorization_code"
code=code_obtained_from_a_url_to_which_keycloak_redirected_the_browser
client_id=client_id_created_using_key_cloak_gui
redirect_uri=the_to_which_keycloak_redirected_the_browser
and reading the body of the response. The content of the body was a json, like the one bellow:
{
'access_token': 'long_token_I_used_latter_as_token_hint_trying_to_logout',
'expires_in': 300,
'refresh_expires_in': 1800,
'refresh_token': 'other_long_token',
'token_type': 'bearer',
'not-before-policy': 0,
'session_state': 'a_shorter_code',
'scope': 'email profile'
}
My logout attempt resulted in the following message in Keycloaks log:
22:53:51,686 WARN [org.keycloak.events] (default task-24) type=LOGOUT_ERROR, realmId=playipintern, clientId=null, userId=null, ipAddress=192.168.16.1, error=invalid_token
and the response said "We are sorry, session not active".
Now I'm aware that I should have used the id_token and not the access_token to logout, but received no id_token in the json.
Somewhere, someone said I should have included
scope=openid
in the parameters that I used to obtain the token. I did it, expecting to find an "id_token" field in the json, but nothing changed.
Someone else reported to have needed to create a scope (I believe using Keycloak's GUI) named "openid" to obtain the token. That didn't make much sense to me, but I tried it anyway and added the just created scope to the client scopes using Keycloak's GUI again. Oncemore, the json didn't change.
I tried to use the refresh_token as the id_token, but that also resulted in an invalid token message.
I don't know what to try now. Any help is appreciated.
Thank you.
/token endpoint returns only the access token by default. No refresh token is returned and no user session is created on the Keycloak side upon successful authentication by default. Due to the lack of refresh token, re-authentication is required when the access token expires. However, this situation does not mean any additional overhead for the Keycloak server because sessions are not created by default.
In this situation, logout is unnecessary. However, issued access tokens can be revoked by sending requests to the OAuth2 Revocation Endpoint as described in the OpenID Connect Endpoints section:
/realms/{realm-name}/protocol/openid-connect/revoke
Example:
POST /revoke HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
token=45ghiukldjahdnhzdauz&token_type_hint=access_token
You need to put your token in place of 45ghiukldjahdnhzdauz.
token_type_hint can take either access_token or refresh_token as value to define which type of token you want to revoke.
You will have to add scope=openid to your initial request to http://example.com/auth/realms/playipintern/protocol/openid-connect/auth (note the /auth instead of /token at the end) before the redirect from where you copied the access code.
You can find further information and explanation in this article.
I am developing an app in c# accessing the CoinBase Api. After the user enters their credentials, I get a code from the api on the callback. I exchange the code for an access_token. I do get a Token with access_token, token_type, refresh_token, expires_in, scope. Everything is populated from CoinBase.
The problem is when I copy that access_token into Postman, I get back invalid_token. Here is how I make the call:
Api Url:
https://api.coinbase.com/v2/user
With these headers:
Content-Type:application/json
Authorization:bearer <access_token here>
CB-VERSION:2018-02-09
The other interesting thing is that if I paste my access_token into jwt.io it can't read it. It shows the headers with lots of weird ascii chars like: mÖߧÜ
Any clues why this is happening? I use the exact calls in Postman on other Api's and they work fine....
Thanks for the insight,
Jeff
After spending the whole night on this, I FINALLY figured it out and wanted to share. I was exchanging code and access_token totally in Postman and I was getting the same error, invalid_token!
Just for fun, I selected the Authorization tab in Postman and selected bearer token from the drop-down. I pasted in my access_token and clicked the preview button. It said my bearer token was applied. I clicked the Send button and viola! It actually worked!! After a few more minutes of investigation, I realized it had put the bearer token auth header in a second time.... hmmm, I removed it, and it failed again. At first I thought Coinbase was broken and needed it in there twice??? Naa, could not be it. So, I removed my auth header line and left the once Postman put in there (effectively changing the order of the headers). That did it!
The Fix: changed my headers to:
Content-Type:application/json
CB-VERSION:2018-02-09
Authorization:Bearer <access_token here>
I believe I am running the exact POST request in the OAuth docs ( with my credentials ), but I'm getting a 400 error. I was getting a 404 error, but then reset my client_secret and started using the new client_secret and am now getting a bad request error. Any ideas what I am doing wrong?
$.ajax({
url:'https://www.googleapis.com/oauth2/v4/token',
data:{
'code':getParameterByName('code'),
'client_id':'',
'client_secret':'',
'redirect_uri':encodeURI(url+'?mail=tokened'),
'grant_type':'authorization_code'
},
dataType:'json',
method:'POST',
success:function(response){console.log(response);}});
Most probably the redirect_uri value that you send is off; it should be exactly the URL that you sent in the authorization request i.e. the redirect to the authorization endpoint earlier.
This may be a long shot, but according to the HTTP/REST example available at Using OAuth 2.0 for Web Server Applications (section Handling the OAuth 2.0 server response) you should be sending the payload with a content type of application/x-www-form-urlencoded instead of JSON.
I've seen other OAuth implementations accepting JSON payload besides the application/x-www-form-urlencoded mentioned in the specification, but maybe Google implementation is more strict.
I've tested your code and it works fine if you have a valid Authorization Code and fill the Client ID, Secret and Redirect URI accordingly. In your snippet client_id and client_secret are set to empty string and this may be why it's not working.
Google OAuth endpoints return nice error messages with the Bad Request responses and can help you discover what is wrong with the parameters you sent.
your grant_type needs to be different than 'authorization_code'. You are having issues while getting tokens.
try grant_type=refresh_token
Redirect URL in .env file should be the same URL in google developer account and also check the redirect url in your route web.php
I am getting the following error when I use the linkedin V1 API:
response body: {
"errorCode": 0,
"message": "[unauthorized]. The token used in the OAuth request has been revoked. 75--5cfb9cdb-3c9c-47c2-b3f8-XXXXXXXX",
"requestId": "I2GQ0ZMWIE",
"status": 401,
"timestamp": 1408976297742
}
I am using this guide here, I am doing exactly what this person is doing but I get a different result:
https://github.com/PrincessPolymath/LinkedIn-OAuth-Sample-Client
I have no idea why I get The token used in the OAuth request has been revoked. for an error. The HTTP request is identical. Could it be something with my bundle ID?
I cannot find anything from linkedin on the matter. Why don't linkedin have normal error-code lookups like other API's.
Here are some photos of the two request objects, one from the example and one from mine.
I'm taking a guess here based on my understanding of the problem you're describing, have not tested this. I'm also assuming you got your credentials right...
You should checkout this answer by Kamyar Mohager (#39), he explains how to bypass this error:
When obtaining access token, error occurs if:
POST https://www.linkedin.com/uas/oauth2/accessToken
Body:
{
grant_type=authorization_code,
code={auth-code},
redirect_uri={uri},
client_id={id},
client_secret={secret}
}
The error WON'T occur if you obtain the access token by passing the params as query params:
POST https://www.linkedin.com/uas/oauth2/accessToken?grant_type=authorization_code&code={auth-code}&redirect_uri={uri}&client_id={id}&client_secret={secret}
Error clearly states that the user is authorized to make a call using the token which you are using.
"message": "[unauthorized]. The token used in the OAuth request has been revoked. 75--5cfb9cdb-3c9c-47c2-b3f8-XXXXXXXX",
In the two photos which you pasted above I can see that your request object has different values "tokenKey and tokenSecret" parameters than the example request object, which is correct as your request should have the token information which received from LinkedIn.
But the thing which I don't understand is why both the request objects have same values for "consumeKey & consumerSecret" parameters. I think you need to use your "consumerKey & consumerSecret" with your "tokenkey & tokensecret" to make this OAuth call. "consumer" and "token" detail combination should match then only you will be allowed to make the successful oauth call.
I guess you saw this error because you used your token with some other consumer key.
One more thing I can see that you are passing the "verifier" in your request object hence I want to know are you making a call to get the "access token" which is a 3rd leg of oauth. If yes then there could be scenario that "requestToken" is getting expired before you are making this "access_token" call as "requestToken" is actually a "temporary token" and expires quickly.
HTH...
The issue was code re-use.
As stated in the comments for the API, the API will give you a token and secret upon the first request. This only happens during authentication and then the token and secret can basically be thrown away, and the one issues at developer.linkedin can be used.
I fixed this by constructing my own request object rather than relying on the old HTTPRequestBody in the oAuth process.