-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
unable to stream API response when token is refreshed #260
Comments
I can confirm that this is a bug, but you don't need to reimplement a client. Before piping, check if the token is expired and refresh token manually if so. You can set the fresh credentials to create a request object to pipe. var oauth2client = // ..
var expiryDate = oauth2client.credentials.expiry_date;
// if no expiry time, assume it's not expired
var isTokenExpired = expiryDate ? expiryDate <= (new Date()).getTime() : false;
if (isTokenExpired) {
oauth2client.refreshAccessToken(function(err) {
// ... insert/update file.
drive.files.insert({
// ...
auth: oauth2client
}).pipe(..)
});
return;
}
// ... insert/update file.
drive.files.insert({
// ...
auth: oauth2client
}).pipe(..) |
good point. Though another reason I implemented my own client was that the oauth client is using the DefaultTransporter which always tries to parse the response body as JSON and in my use-case (downloading a file from g-drive) that is definitely unnecessary and I dont see an easy way to make it stop doing that except for replacing the .transporter with my own transporter or overriding its private "wrapCallback_" method which i dont want to do. |
I have the same problem. Refreshing token helps before piping... |
I spent some time tracking this down in my program and I'm surprised to see it's already known :-) Perhaps Or maybe |
Good news! This is no longer an issue. Since switching from request to axios, it now means that the pipe is done on a res.data object that is only returned after a successful refresh. You can see a sample of this in action here: Hope this helps! |
Hello, please keep in mind im fairly new to node development so some of my assumptions may be wrong.
Im working on an app that allows downloading files from g-drive offline, as in the server keeps the user's token so it can access their files without needing to login every time.
I want to be able to stream the content of a drive file to the fs so I use a write stream (fs.createWriteStream).
I tried using the oauth2client (https://github.com/google/google-api-nodejs-client/blob/master/lib/auth/oauth2client.js) but that proved impossible for the reason that in all likelihood, the token stored by the app has expired and requires refreshing.
In short, pipe works when the token doesnt require refreshing and doesnt when the token has expired.
In detail, the issue is that if you follow the flow of the oauth2client code (specifically the request method) you see that it checks the expiry date and if passed it will make a request to refresh the token. This request is over HTTP so is asynchronous. At this point, the request method will not be able to return the result from calling "this._makeRequest..." which is actually the return object from calling on the request module (https://github.com/mikeal/request), which is the object needed for calling "pipe()" on.
Unfortunately, this meant I had to write my own client/transporter which is what I did here:
https://gist.github.com/yoavniran/06454e87a3b8d858614e#file-simpleauthtransporter-nodejs
My class relies on emitting events so it can expose the request object even if a token refresh is needed.
I didn't want to write my own code for this but couldnt find a better solution. If there is one Id love to learn and if not I wonder if something like my solution can be integrated into the oauth2client code?
thanks,
Yoav
The text was updated successfully, but these errors were encountered: