I'm using npm package 'request' to make API calls. Upon initial login, I should receive a cookie back, I need to store that cookie indefinitely to make subsequent calls.
I'm doing this in Python with requests like so:
#set up the session
s = requests.session()
#logs in and stores the cookie in session to be used in future calls
request = s.post(url, data)
How do I accomplish this in node? I'm not tied to anything right now, the request package seems easy to work with, except I'm having issues getting known username and passwords to work, that said, I'm sure that's mostly my inexperience with JS/node.js.
This is all backend code, no browsers involved.
I need to essentially run a logon function, store the returned encrypted cookie and use for all subsequent calls against that API. These calls can have any number of parameters so I'm not sure a callback in the logon function would be a good answer, but am toying with that, although that would defeat the purpose of 'logon once, get encrypted cookie, make calls'.
Any advice, direction appreciated on this, but really in need of a way to get the cookie data retrieved/stored for future use.
The request package can retain cookies by setting jar: true -
let request = request.defaults({jar: true})
request('http://www.google.com', function () {
request('http://images.google.com')
})
The above is copied near-verbatim from the request documentation: https://github.com/request/request/blob/master/README.md#requestoptions-callback
Related
I have successfully set up the feedly developer access token using the javascript library Axios on a NuxtJS site. I am having trouble, though, figuring out how to set up the refresh token.
This is the process I have used for the developer token
export default function({ $axios }) {
$axios.onRequest((config) => {
config.headers.common['Authorization'] = [FEEDLY_ACCESS_TOKEN]
})
}
This code gets run whenever I make the relevant axios request.
What I am wondering, now, is what I need to do for the refresh token. I have taken a look at the instructions on these two pages:
https://developer.feedly.com/v3/developer/#what-happens-once-the-developer-access-token-expires
https://developer.feedly.com/v3/auth/#refreshing-an-access-token
However, I'm still not 100% clear as to what I am supposed to do. In particular, I have two questions:
Do I also run the refresh token each time I make an axios call -- or should I create a function that runs every thirty days and runs the code.
How exactly do I make the axios call for the refresh token. My initial guess is something like this:
$axios.$post('https://cloud.feedly.com/v3/auth/token/?refresh_token=FEEDLY_REFRESH_TOKEN&client_id=feedlydev&client_secret=feedlydev&grant_type=refresh_token')
Is that correct? If not, what do I need to change.
Thanks.
Different developers will use different strategie regarding refreshing an access token. While some will return a new token on every request, other will do it over a term of days or longer.
The idea is to reduce the window of risk in which an access token can be abused but it is sort of a subjective topic imo. Obviously there is a performance penalty when you generate a new access token on every request. Sometimes this may be acceptable, but I really don't think it's necessary in many cases. Measure the tradeoff between the penalty and the sensitivity of the token in your case.
The docs explain it well:
Endpoint:
POST /v3/auth/token
It does say that using url parameters is not recommended, so why not just do it the way they recommend it? Either:
using a x-www-form-urlencoded POST request (standard)
as a JSON object (make sure you set the Content-Type header to “application/json”)
You have more questions around this?
Based on the Netflix Hystrix circuit-breaker design pattern i was trying to do the following:
const circuitBreaker = require('opossum');
import * as request from 'request-promise';
const circuit = circuitBreaker(request.get);
circuit.fallback(() => Promise.resolve({result:[]}));
I have 3 node js services deployed . They use a circuit-breaker(opossum) to make REST Calls in between them. I have a fallback method which handles the scenario when a service goes down. I was wondering if something like request-caching can be used alongside the circuit breaker to return cached response whenever the fallback is invoked. If yes, how can i achieve this ?
P.S : request is my client to make REST calls
As far I know opossum does not provide a out of the box solution for your problem. You have to implement some mechanism to cache the latest successful call. In my point of view probably the best way to do it, is having some distributed cache like Redis and cache the latest successful response but make sure to have a temporary entry in Redis you don't want to return old deprecated data.
I'm not sure if this can help but you can try:
circuitBreaker(request.get, { cache: true });
You can see a bit more details on this test file
All meteor methods can be called same way from client and server side.
Let's say user knows or can predict all the method names on server, then he is able to call them and use it's result however he want.
example:
A method which performs cross domain http request and return response can be used to overload server by calling huge amounts of data Meteor.call(httpLoad, "google.com");, or a method which load data from mongo can be used to access database documents if the client know document _id Meteor.call(getUserData, "_jh9d3nd9sn3js");.
So, how to avoid this situations, may be there is a better way to store server-only functions than in Meteor.methods({...})?
Meteor methods are designed to be accessed from the client, if you don't want this, you just need to define a normal javascript function on the server. A really basic example would be:
server/server.js:
someFunction = function(params) {
console.log('hello');
}
As long as it's in the server folder, the function won't be accessible from the client.
For coffeescript users, each file is technically a separate scope, so you would have to define a global variable with #, e.g.
#someFunction = (params) ->
console.log 'hello'
or if you want to scope the function to a package:
share.someFunction = (params) ->
console.log 'hello'
If you have methods that need to be accessible from the client but only for say admin users, you need to add those checks at the start of the meteor method definition:
Meteor.methods({
'someMethod': function(params) {
var user = Meteor.user();
if (user && (user.isAdmin === true)) {
// Do something
} else {
throw new Meteor.Error(403, 'Forbidden');
}
}
});
I'm not going to vouch for the security of this example - it's just that, an example - but hopefully it gives you some idea of how you would secure your methods.
EDIT: Noticed the other answers mention using a if (Meteor.isServer) { ... } conditional. Note that if you are doing this inside methods which are also accessible on the client, the user will be still be able to see your server code, even if they can't run it. This may or may not be a security problem for you - basically be careful if you're hardcoding any 3rd-party API credentials or any kind of sensitive data in methods whose code can be accessed from the client. If you don't need the method on the client, it would be better to just use normal JS functions. If you're wrapping the whole Meteor.methods call with a isServer conditional, the code will be on the server only, but can still be called from the client.
as rightly stated in other answers, your methods will always be accessible from the client (per design). yet, there is a simple workaround to check if the call originates from the client or from the server. if you do a
if ( this.connection == null )
this will return true if the method was called from server. like that you can restrict the method body execution to 'secure' calls.
I think this page explains it: http://meteortips.com/first-meteor-tutorial/methods/
I'm quoting:
"The safer approach is to move these functions to the isServer conditional, which means:
Database code will execute within the trusted environment of the server.
Users won’t be able to use these functions from inside the Console, since users don’t have direct access to the server.
Inside the isServer conditional, write the following:
Meteor.methods({
// methods go here
});
This is the block of code we’ll use to create our methods."
and so on. I hope this helps.
With proper app design, you shouldn't care whether a request was through the web UI or via something typed in a console window.
Basically, don't put generic, abuse worthy functions in Meteor.methods, implement reasonable access controls, and rate-limit and/or log anything that could be a problem.
Any server-side function defined in Meteor.methods will have access to the current user id through this.userid. This userid is supplied by Meteor, not a client API parameter.
Since that Meteor Method server-side code knows the login status and userid, it can then do all the checking and rate limiting you want before deciding to do that thing that the user asked it to do.
How do you rate limit? I've not looked for a module for this lately. In basic Meteor you would add a Mongo collection for user actions accessible server-side only. Insert timestamped, userid specific data on every request that arrives via a Meteor method. Before fulfilling a request in the server method code, do a Mongo find for how many such actions occurred from this userid in a relevant period. This is a little work and will generates some overhead, but the alternative of rate-limiting via a server-wide underscore-style debounce leaves a function open for both abuse and denial-of-service by an attacker.
I need to retrieve a facebook page's list of posts (feed) using their javascript SDK, just like they explain in their docs: https://developers.facebook.com/docs/graph-api/reference/v2.4/page/feed
/* make the API call */
FB.api(
"/{page-id}/posts",
function (response) {
if (response && !response.error) {
/* handle the result */
}
}
);
I need it to be my website's "news section", so users should see it even if they are not connected to facebook.
The problem
Cool, but there is a problem... It returns: An access token is required to request this resource.
Holy cow... I'd like to get some access token for you #facebook, but my app doesn't make use of your authentication tools/plugins.
ANYWAY, I tried with FB.getLoginStatus(); but doesn't work, because the only way it can return an access_token is if the user is actually connected to the application. My users may not even be logged to facebook!
So, ¿How can I get an access_token to be stored into a variable, and later be used to get /{my-page}/posts?
I've already payed a look to this SO question, but it doesn't solves my problem, simply because there are no such "generic tokens".
I've also read https://developers.facebook.com/docs/facebook-login/access-tokens/ and that also relies on tokens generated through facebook login methods... So, can't I display a list of fb page's posts in my website, without being connected into facebook, hence an application?
ADD: My app is build with angularJS, I'm not dealing with server-side code. I shall rely purely on javascript methods.
You could either use an page or an app access token, but as you'd be using them on the client-side, neither of them are an option.
See
https://developers.facebook.com/docs/facebook-login/access-tokens#apptokens
https://developers.facebook.com/docs/facebook-login/access-tokens#pagetokens
Note that because this request uses your app secret, it must never be made in client-side code or in an app binary that could be decompiled. It is important that your app secret is never shared with anyone. Therefore, this API call should only be made using server-side code.
I'd strongly recommend to build a simple server-side script (PHP for example) to proxy the request to the Graph API. You could then call this via AJAX for example and load the posts asynchronously (and alse get rid of the FB JS SDK!). There is NO way to handle this in a secure manner if you don't want to use FB Login for all of your users (which also doesn't make much sense IMHO).
I think it's straightforward :)
Since pages' posts are always public, it only needs a valid access token to retrieve page posts.
Quoting what you've written:
So, ¿How can I get an access_token to be stored into a variable, and later be used to get /{my-page}/posts?
You only require an access token.
My suggestion would be;
- Generate an access token for yourself (no extra permission needed)
- request page-id/posts
This way you don't require other users to be connected to facebook, you can simply requests page-id/posts to retrieve posts with access token you generated for yourself.
I hope it solves your problem :D
TIP: As long as posts are public, you only require a valid access token, it doesn't need to be user or page specific.
I am writing a web app in node.js. Now every processing on the server is always in the context of a session which is either retrieved or created at the very first stage when the request hits the server. After this the execution flows through multiple modules and callbacks within them. What I am struggling with is in creating a programming pattern so that at any point in the code the session object is available without the programmer requiring it to pass it as an argument in each function call.
If all of the code was in one single file I could have had a closure but if there are function calls to other modules in other files how do I program so that the session object is available in the called function without passing it as an argument. I feel there should be some link between the two functions in the two files but how to arrange that is where I am getting stuck.
In general I would like to say there is always a execution context which could be a session or a network request whose processing is spread across multiple files and the execution context object is to be made available at all points. There can actually be multiple use cases like having one Log object for each network request or one Log object per session. And the plumbing required to make this work should be fitted sideways without the application programmer bothering about it. He just knows that that execution context is available at all places.
I think it should fairly common problem faced by everyone so please give me some ideas.
Following is the problem
MainServer.js
app = require('express').createServer();
app_module1 = require('AppModule1');
var session = get_session();
app.get('/my/page', app_module1.func1);
AppModule1.js
app_module2 = require('AppModule2');
exports.func1 = function(req,res){
// I want to know which the session context this code is running for
app_module2.func2(req,res);
}
AppModule2.js
exports.func2 = function(req,res){
// I want to know where the session context in which this code is running
}
You can achieve this using Domains -- a new node 0.8 feature. The idea is to run each request in it's own domain, providing a space for per-request data. You can get to the current request's domain without having to pass it all over via process.domain.
Here is an example of getting it setup to work with express:
How to use Node.js 0.8.x domains with express?
Note that domains in general are somewhat experimental and process.domain in particular is undocumented (though apparently not going away in 0.8 and there is some discussion on making it permanent). I suggest following their recommendation and adding an app-specific property to process.domain.data.
https://github.com/joyent/node/issues/3733
https://groups.google.com/d/msg/nodejs-dev/gBpJeQr0fWM/-y7fzzRMYBcJ
Since you are using Express, you can get session attached to every request. The implementation is following:
var express = require('express');
var app = express.createServer();
app.configure('development', function() {
app.use(express.cookieParser());
app.use(express.session({secret: 'foo', key: 'express.sid'}));
});
Then upon every request, you can access session like this:
app.get('/your/path', function(req, res) {
console.log(req.session);
});
I assume you want to have some kind of unique identifier for every session so that you can trace its context. SessionID can be found in the 'express.sid' cookie that we are setting for each session.
app.get('/your/path', function(req, res) {
console.log(req.cookies['express.sid']);
});
So basically, you don't have to do anything else but add cookie parser and enable sessions for your express app and then when you pass the request to these functions, you can recognize the session ID. You MUST pass the request though, you cannot build a system where it just knows the session because you are writing a server and session is available upon request.
What express does, and the common practice for building an http stack on node.js is use http middleware to "enhance" or add functionality to the request and response objects coming into the callback from your server. It's very simple and straight-forward.
module.exports = function(req, res, next) {
req.session = require('my-session-lib');
next();
};
req and res are automatically passed into your handler, and from their you'll need to keep them available to the appropriate layers of your architecture. In your example, it's available like so:
AppModule2.js
exports.func2 = function(req,res){
// I want to know where the session context in which this code is running
req.session; // <== right here
}
Nodetime is a profiling tool that does internally what you're trying to do. It provides a function that instruments your code in such a way that calls resulting from a particular HTTP request are associated with that request. For example, it understands how much time a request spent in Mongo, Redis or MySQL. Take a look at the video on the site to see what I mean http://vimeo.com/39524802.
The library adds probes to various modules. However, I have not been able to see how exactly the context (url) is passed between them. Hopefully someone can figure this out and post an explanation.
EDIT: Sorry, I think this was a red-herring. Nodetime is using the stack trace to associate calls with one another. The results it presents are aggregates across potentially many calls to the same URL, so this is not a solution for OP's problem.