We have an problem while designing new API. The problem is that we have an MVC project and we want to connect it with new API. Our idea is simple (showed on graph): Graph here!
The problem is that we don't want 'ask' API for new authorization token (jwt authorization) every single time when we put message to queue. We invented that we can check if token not expired when we tried to put message to queue (ExpiredProperty in MVCApp memory). Anyway the situation may occur that token is valid to for e.g. 2018-01-01 00:00:10 and when we try to put message the date is: 2018-01-01 00:00:09.321 so for our program is still valid.
On API side we just take message from function decode this and check if token is valid (have api secret key, not expired) then if its ok we will put this message into AzureTable, but if it's not we don't know what we can do with this message.
We can't 'forget' this invalid message and also we can't let this message to be putted into db.
Have you got any idea how we can handle this?
Thanks for all responses.
Related
I managed to get the access_token and refresh_token on front end and now its stored in a database, On the backend .netcore application I create googlecredential with
var cred=googleCredential.fromAccessToken(access_token);
but this one doesn't refresh on its own and I have no idea how to refresh this. I can send a post request to their rest api and refresh it but I need to know when "creds" has expired to send that refresh request. PS know that the tokens are in a database so using anything but .fromaccesstoken is not an option.
EDIT:
Complete code can not be shared but here's how the application's flow is going. On a reactJS application I get the authorization code via react-google-login module
<GoogleLogin
clientId="xxx"
buttonText="Login"
onSuccess={this.responseGoogle}
onFailure={this.responseGoogle}
cookiePolicy={"single_host_origin"}
scope="https://www.googleapis.com/auth/drive.readonly"
accessType="offline"
prompt="consent"
responseType="code"
/>
this returns an authorization code as the only response body, this response is then used with another endpoint to exchange for refresh and access token at front end, these tokens are sent to a backend endpoint which stores them in a db. Now the server side can create a googlecredential object via
this.googleCredentials=GoogleCredential.FromAccessToken(this.googleAccessToken);
Only problem being this doesnt handle the refreshing on its own so you have to somehow implement it.
Since I can't find another way to refresh when GoogleCredentials object is created via fromtoken(ACCESS_TOKEN) what I've done is sending a post request with the refresh token that I have to the rest endpoint at the backend and get a new access_token.
Another problem faced was finding out when the access token was expired for which no solution could be found. But it returns a 401 exception at creating the drive folders via drive service in my case
var res = await this.driveService.Files.Create(folder).ExecuteAsync()
here res will raise an exception and I just put it in a try block and got the new access token via http request in catch and ran the statement again (hint: recursion)
Hope this helps anyone, but better proposed solutions will be welcomed. Please understand that this is going to be a backend solution reading refreshtoken from database.
I have created a Rocket Chat server locally (version 2.4.11) and i'm trying to send a message to an user through the REST API.
The program is written in C#, and uses the HttpWebRequest to create each call, then the WebResponse class to receive each response, parsing it's contents (witch are JSON based data, according to Rocket Chat REST API documentation).
My calls are 4 fold, in that order, to:
1 - LOGIN ("api/v1/login" url, passing as JSON a user and password for the "sender" user)
2 - IM.CREATE ("api/v1/im.create" url, passing the X-Auth-Token and X-User-Id data at the headers, and the JSON for "username" of the destination account, in order to create - or find - a room id to call the next API with)
3 - SENDMESSAGE ("api/v1/chat.sendMessage", again with the X-Auth-Token and X-User-Id headers, and a JSON with the Room Id provided by last call, with the message as well)
4 - LOGOUT ("api/v1/logout", with the user header data to end the connection/session)
When i use my own account (witch was the first account created, with ADMIN role) to send to any other account, it works and the message is sent - every step receives a response according to the documentation and passes to the next call - but when i use a bot account (such as rocket.cat) or even if i use any other account, with user o admin roles (created a new account with ADMIN role to test it) the calls don't work after the IM.CREATE, that returns with no data on the JSON response.
Is there anything that i need to activate when creating a new account to allow it to work (even if the role is ADMIN)? Is that the correct order and API's to use to send a message to a user (not to a group of people, but to 1 person, as an IM)?
UPDATE
Posted the issue on GitHub (rocket chat project) on REST API, Error 400 calling after Login #17334
So, as it turns out it was something that i didn't know about causing this error - the recipient address is case-sensitive, and a account name "user" and "User" are not found by the API unless it matches the exact case. Althought it passes on the login API (wich is case-insensitve), the im.create is not, so the sender name doesn't need to mach, but any recipient must.
I’m writing a web api that will be called from a background service to fetch some data. After some research I decided to use a Json web token to achieve that but I’m still a bit confused regarding when a new token should be requested.
Let’s say I start up my service, I request a token, the token expires after 15 minutes, then after 20 minutes I make an api call with the expired token. I will get an unauthorized error or something.
My question is: How will the client know when to request a new token? Should it request a new one before every api call? Seems like I’m missing something. Maybe I should make the token permanent and store it in the database?
Thanks
The answer to this is slightly application specific, but the OAuth specification has a mechanism for "refresh tokens", which can be used to grant new "access tokens" (the token typically included on each API request), without having to send the user to the UI authentication process to have them re-authenticate. So, once you request an access token, you will receive a refresh token and an access token. This methodology allows access tokens to be used for much shorter time frames.
This can also be done without refresh tokens, but in those cases the access token timeout would likely be longer, and then you would request that the user re-authenticate through the usual OAuth UI process. Note that even when you do have refresh tokens, the refresh token can also be set to expire, in which would then require a user re-authentication through UI again.
In some API's you just make the API request as usual, and if you get a response that is defined by the API to be one that indicates the access token has expired, you can then issue an API call to refresh the token (or fully request a new one if that is expired, or you the API doesn't have refresh tokens), and then make the original API call again with the new access token.
The API can also have a response that includes the timeout or expiration date/time of the access token as well. Then, the client can avoid sending the initial API call first, and simply send the refresh token call first.
In implementing your API, you could likely use any of these methodologies.
Here's some general discussion on the OAuth spec website, to provide more depth:
https://www.oauth.com/oauth2-servers/making-authenticated-requests/
https://www.oauth.com/oauth2-servers/access-tokens/access-token-lifetime/
https://www.oauth.com/oauth2-servers/access-tokens/refreshing-access-tokens/
And also, here's an example from the Twitter API regarding response codes showing one of the access token expiration techniques (see the "Error Codes" section, under error code 89, which implies the token has expired and you need to get a new one):
https://developer.twitter.com/en/docs/basics/response-codes
Since your client is background service , you can use the Oauth2 Client Credential Flow . Your background service can request an access token using only its client credentials when the client is requesting access to the protected resources under its control.
With this flow , you does't need to care much about the token expires , if client sends an expired token to web api , web api validate the token and create token expires response to your service , your service check the status code/response , directly send a new token request to web api to get new access token , there is no need to use refresh token which uses in other flows .
The fact is that your harness should be prepared to request any token when getting an Unauthorized status code. What I do in test is to check the expiration datetime, if close enough I refresh or get a new token whatever applies to your Auth. Also when getting an unauthorized status code my code does a refresh once and keep a count. If I get another unauthorized code then I return a false or throw an exception after I log the error on the second try. This works fine for me.
So, I've basically got this working, except for one issue. I've got a google service account set up so it can access our domain contacts. And it can batch query them perfectly!
But if I call cr.Retrieve("some-contact-url-here"), it throws an error griping about not having a Refresh token. I'm using a service account though, so I don't get a refresh token when I authenticate.
And I can't seem to find any good answer as to how I'm supposed to get a refresh token for a service account. There's one or two stackoverflow posts which actively mention getting a refresh token with a service account....but what they linked to has since been redirected. Anything else I've found to do with refresh tokens has basically been about authenticating manually and storing the token. Because I need to use a Service Account, that is not a possibility.
A service account's credentials, which you obtain from the Google Developers Console, include a generated email address that is unique, a client ID, and at least one public/private key pair. You use the client ID and one private key to create a signed JWT and construct an access-token request in the appropriate format. Your application then sends the token request to the Google OAuth 2.0 Authorization Server, which returns an access token. The application uses the token to access a Google API. When the token expires, the application repeats the process.
Check this page for more information.
Ok, based on several hours of bashing my head violently against the API, it looks like there's basically no way to get a refresh token when you're authenticating as a Service Account. Expected behavior, really.
Anyway, to get around the issue, you can load all of the contacts into memory,
feed.AutoPaging = true;
foreach (var c in feed.Entries)
{
contactList.Add(c);
}
And you can update|delete|etc then. Grossly inefficient though. Especially if your contact list gets rather big.
I am attempting to create a payment profiles using express checkout with an old NVP .NET (C#) API implementation. The version is 65.1.
After I perform a SetExpressCheckout, I get a successful response. The user is sent back to my test site, and I attempt to CreateRecurrentPaymentProfile. I pass in the url-decoded token, set the billing agreement description the same as the first step, and fire off the request. I always get an "The token is invalid" error. I've gone through and made sure I included all the required information from this page: https://developer.paypal.com/docs/classic/api/merchant/CreateRecurringPaymentsProfile_API_Operation_NVP/.
I also know that we are set up to allow for recurring payments because the recurring charges over direct payments currently works.
I know that everybody and their dog has had this issue when working with PayPal's NVP API at one point or another, but of the umpteen internet threads and discussions, none of them have helped. Any suggestions?
You should be using the same token returned in the response to your SetExpressCheckout. The token is good for 3 hours once it is returned so it isn't expired. Perhaps the token is corrupted somehow, with an extra character, or perhaps a character was omitted. The token should look similar to this: EC-5UG654898R029060W.
To reiterate: You get a valid token from the SetEC, you use this token in the redirect, you get this token back appended to the RETURNURL the customer returns to, and you reference this token in any subsequent GetEC and DoEC, CreateRP calls.