-
Notifications
You must be signed in to change notification settings - Fork 24
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
refresh_token flow #10
Comments
Passport doesn't handle token expiration, it fetches them and uses them once to load user profile. Here's a relevant thread on passport issues. As for how you should act in this situation - simply fetch a new token from Reddit, as shown here. Be careful, though, you do want to run refresh only once to avoid race conditions. In a simple single-process case you can simply wrap your refresh in a code, that will collect all the callbacks and run them once refresh is done. If you use cluster or even multi-server architecture, you have a bit of a challenge in front of you, though moving API connector to a separate process might help. |
Thanks Slotos. Can I use I don't quite understand your last paragraph, what do you mean by "run refresh only once"? Do you mean if a user clicks 'vote' (or anything) again while I'm waiting for the first request to come back? |
It's all on your shoulders, I'm afraid. Passport simply doesn't get involved at all. You can reuse strategy.js code, that sets up Basic Auth headers, however.
Pretty much. If you don't account for it, you'll have different requests refreshing your tokens before other ones had a chance to use a refreshed one. It is also not unlikely to get your app blocked on reddit side. |
Awesome, thanks so much. My solution (I'm using the 'request' module) looks something like this: function refreshRedditToken(req, res, cb) {
req.session.tokenRefreshInProgress = true; //this is set tested before calling this function
var refreshToken = req.user.reddit.refreshToken;
var options = {
url: 'https://ssl.reddit.com/api/v1/access_token',
form: {
grant_type: 'refresh_token',
refresh_token: refreshToken
},
auth: {
user: REDDIT_CLIENT_ID,
pass: REDDIT_CLIENT_SECRET,
sendImmediately: true
},
json: true,
headers: {
'User-Agent': 'my UA goes here'
}
};
request.post(options, function(err, httpResponse, data) {
//error handling omitted
req.user.reddit.token = data.access_token;
//write the token to the database
userController.updateToken(req.user._id, data.access_token, function(err) {
req.session.tokenRefreshInProgress = false;
cb(err); //callback would try the original action (e.g. vote) again
});
});
} |
Note of warning, be careful with session data handling. Your code will not work as you might expect it to if you use cookies as session storage. Unlike server-side storages, it won't update till you respond to client's request. |
Oh, yeah that's a gotcha! So (newbie question) what is the best way to set a variable server side for a user? |
Generally server-side out-of-process session storage works quite well. While adding some overhead, it will behave persistently for single-process, multi-process and to some degree even for multi-server deployments. However, it still won't save you from races (I must sound repetitive at this point), it will simply move the control over opportunity window to your side. I.e. instead of having reddit delay determine races, session storage update speed will. But at this point it is good enough to let it occasionally fail with intelligent error message. Fully strengthening it against such races might not be worth the development time past this point (though it's quite fun and frustrating activity). |
Hi,
I can't get the refresh_token process to work. My initial authentication works:
Now, I can, say, vote (via an AJAX call from the client) on a reddit link and it works fine. After an hour, the token expires as expected and I get an
{error: 401}
response when I try to vote. So when this happens I want to go away in the background, update my token using the refresh token, then continue on with the voting call. So I try this (in the callback from the vote request):But this tries to redirect the client so I get this error (in the browser console):
XMLHttpRequest cannot load https://ssl.reddit.com/api/v1/authorize?response_type=code&redirect_uri=[my callback url]&scope=identity&client_id=[my client id]. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
Please forgive me if this is the wrong place to be asking, I'm not sure if it's an actual issue with passport-reddit or not. I suspect it's me just not understanding something.
Thanks heaps in advance...
The text was updated successfully, but these errors were encountered: