I just installed the MEAN stack (MongoDB, Express.js, AngularJS, Node.js) and opened up the example program (as found on mean.io) and they have a basic app that you can login to and create blog "articles" just for testing and such.
Anyway, I removed the '#!' from the URL and it outputted the entire user and article models as they are in the database. It seams as though doing that made it stop routing through Angular and instead used the Express routes which are just JSON REST apis. Is this a flaw in the MEAN stack package, Angular as a whole, or maybe just a development environment setting? I can't imagine that this would be released with a huge flaw like that but maybe I'm just missing something..
Replicateable steps:
Follow installation instructions on http://mean.io
Goto your local app in the browser and create an account and login
Create an article
View the article item you just created and remove the #!/ from the URL, you then see the JSON object of your logged in user account
complete with hashed password and salt, as well as the article
object.
Its just an app configuration. If you change the routes.js from:
app.get('/articles', articles.all);
to
app.get('/articles', auth.requiresLogin, articles.all);
Then if you try and hit the url /articles directly you get the message:
"User is not authorized"
Instead of JSON listing all the articles.
As you say, removing the #! causes the routing to be handled by the server. The node API then dumps the user object in the response.
The problem is completely independent from Angular - the app is only served by Node at the / route. Angular then uses the hash value to show the correct page.
This is probably just a problem with the example provided by MEAN. The app itself is insecure, when they talk about best practices that refers to the code structure and setup rather than the quick demo.
You could ask them about it, since there will probably be people who build on top of the example and don't fix the security issues.
Related
I'm trying to use fetch method to get/post data into a REST server (this is working), but some users of my app need to do this over a network(WiFi) with proxy authentication. I've searched this, I found a few answers, but no one have helped me, some doesn't work 'cause need the Node core modules (that isn't on React-Native packager), e.g: https-proxy-agent.
Here I've found a similar question: react-native-fetch-through-proxy, but axios don't supports proxy with user and password (I tried), and the unique answer doesn't worked for me, 'cause it need Node core modules (again).
I tried browserify to implement pieces of Node core, but the https-proxy-agent plugin can't see my JS files.
I'd like to create a site with Angular (I'm new), but also want to be able to have different "views" be cachable in the search engines and have their own URL routes. How would I achieve this with Angular, or is best not to use it?
Enable pushState in Angular with $locationProvider.html5Mode(true); so that you have real URLs and make sure that, when the URL is requested by the client, you deliver the complete page for that URL from the server (and not a set of empty templates that you populate with JS).
When a link is followed, you'll go through an Angular view and update the existing DOM (while changing the URL with pushState) but the initial load should be a complete page.
This does mean duplicating effort (you need client and server side versions of the code for building each page). Isomorphic JS is popular for dealing with that issue.
If you want to expose Angular views to search engines and other bots, I suggest using an open source framework that we developed at Say Media. It uses node.js to render the pages on the server when it detects a bot vs a real user. You can find it here:
https://github.com/saymedia/angularjs-server
I would suggest not using different routes, however, as most search engines will penalize you for having duplicate content on multiple urls. And while you might think they would just hit the bot version of your site, they are getting more sophisticated about crawling single page app like sites. I would be cautious about duplicate routes for the same content.
Good Luck!
Circumstances
I develope a WebApp with AngularJS.
I've an restful API on server-side with GET and POST commands.
I want to use the API within my module (means: in JavaScript) to display and edit my data.
I want to protect the API with some kind of authentication (basic auth with an API key for example)
I don't want to protect the API when a user uses the app itself
Actual question
Okay, I guess the last point is a bit unclear.
I want that a user can use the app with his browser without any authentication
But when a third-party app want to access the API it have to use authentication
Since JavaScript is executed on client-side of course I can't write a master key into js or something similar..
Is there any kind of pattern or solution to solve this problem?
More specifications
referring to #EliranMalka and #shaunhusain
On the server-side I do use Tornado with it's builtin template engine. I do use the template engine actually just to write the index page and insert CSS, JS dynamically.
The code for authentication would just something like:
def is_authenticated(request):
if 'api_key' in request.arguments:
return sql('SELECT id FROM keys WHERE key=%S' % request.arguments['api_key']).count == 1
My AngularJS module is doing something similar to:
$http.get('/api/foo?api_key=1234')
.then(function (result) {
$scope.data = result.data
});
As you can see I'm writing my API key into js at the moment. But I wan't to avoid this.
Also, what do you mean exactly by third-party?
not a third-party request would be: Using the App on http:/ /app.example.com with a browser
A third-party request would be from an Android app for example. Something that comes from outside or remote.
A JS request from the browser on the actual page would be not from remote (again: since it's JS it is actually from remote - but I hope it gets more clear now)
Oh and before I forget...
I'm aware of that my plan is a bit weird - but it's just a learning(-web-development)-by-doing project.
Also the API key is not absolutely to avoid abusion, it is rather to log 3rd-party usage.
PS I hope my question was clear for you
Hmm, well I'll try to address the questions but here's a few things.
Question isn't really appropriate in it's current format for stackoverflow.com (should be programming questions, I tried X and Y happened) perhaps closer to a StackExchange question but is still fairly open ended.
Include more information about specifics of the languages (and/or frameworks) your using server side and any code you have that is relevant (authentication code?).
Putting the key into the client code and transmitting it from the client means anyone with a web proxy (check out Charles or Wireshark) can grab the key so just to reiterate you're right there that's not the way to go.
Check out how other organizations allow you to get access to their APIs (for example Google, LinkedIn, Facebook, Twitter) to get a feel for how it works. In all of these cases you are signed into the service to be able to make an API key, in some cases you have to specify which domain the requests with that API key will come from. If you use the same precautions and check the API key sent with a request against a database of registered API users and verify the domain in the request then I'd say you're in pretty good shape.
I have developed a rails app that currently uses a lot of javascript.
Most of this javascript is code that I have generated myself, and is generally only used in a few places (all by authenticated users).
Basically, what I would like to do, is to be able to only allow a user access these js files if they are logged in and authorized (I use devise and cancan for authentication and authorization).
I would still like the files to be precompiled (concatenated and minimised) the same as the asset pipeline does, but these files should then be stored somewhere not accessible to the public, and served by rails (or similar) only when the user is authorized to access them.
I have tried and failed searching, but feel I must be missing something simple as this is surly common practice in a lot of rails apps.
Therefore, I was hoping to get some help finding information on this matter as I'm at a loss of what I can do other than compiling the js file manually and adding this to a view the user is authorized to access.
Any help would be appreciated!
Edit:
To Clarify what I'm asking:
I want to try to find something similar to the asset pipeline that will concatenated and minimize the js files as normal.
Then, when the user tries to access this js file:
1. If the user is logged in, the js file is served to the user as normal.
2. If the user is not logged in, the user is given a error message (or a 401 not authorized, or 404 not found, or similar), meaning a unauthorized user cannot access the script.
Basically, something similar as what happens when you try to access a json file you arn't entitled to view.
you could simply use different layouts for the logged-in users or render a partial, that includes your precompiled javascript.
e.g. in application.html.haml
- if current_user.
= javascript_include_tag "your_special_user_js"
I don't know, if this answers your question, but it was my understanding, that you are trying to achieve this behaviour.
I'm working on a basic personal homepage, consists of a single html document, a .css and jquery*.js file. I want to create a blog-ish look via fetching page content from tweets. The standart widget doesn't fit to the look of the page.
I can fetch public tweets from any account with no authentication crap (it's crap because it public data anyway) via API v1. But with API v1.1, it returns authentication error. It wants me to authenticate to fetch public data. Try to navigate this url. it shows ({"errors":[{"message":"Bad Authentication data","code":215}]});.
My question is is there a way to fetch public tweets via client side js? I don't want to create an app to just fetch public data. I don't wan't to use identi.ca or else, but Twitter pushes me to do.
Upon the comment of Zachary Kinebel to Norguard's answer, I thought, as a comment of Norguard's might be helpful to others, I should put it here:
/search.json?q=from:nerdswguitars === recent tweets by NerdsWGuitars /search.json?q=to:nerdswguitars === recent tweets to NerdsWGuitars /search.json?q=from:nerdswguitars OR to:nerdswguitars === both. /search.json?q=#nerdswguitars === posts involving NerdsWGuitars. /search.json?q=#nerdswithguitars === posts trending "nerdswithguitars". But you MUST make sure that you're properly URL encoding the query. Read more here: https://dev.twitter.com/docs/using-search and if you can't find what it is that you're looking for, out of this, then you need to be a lot more specific
EDIT
In the wonderful world of bad ideas, Twitter is sunsetting this answer, as of May 2013, and will require, at minimum, that you either use one of their widgets, and shoehorn it in, or that you set up an application and do application-level authentication, even for public-timeline GET requests.
If they change their mind, or delay the throwing of the switch, this will at least continue to be here.
Use the Search API:
"http://search.twitter.com/search.json?q=nerdswguitars"
You can use the URL-encoded # or # in front of search terms. You can also use keywords like from or to, and specify limits, et cetera.
You can use Mooch, a small application designed to solve this exact problem. Setting up a new Mooch service is very simple, and utilizes Heroku. The
deployment process requires the Heroku Toolbelt application.
Step 1: Create a Twitter app
Visit https://dev.twitter.com/.
Sign in with a Twitter account.
Create a new application.
Step 2: Get Mooch
Clone the Git repository (git clone git#github.com:eloquent/mooch.git).
Change into the Mooch root directory.
Step 3: Create a Heroku app
Sign in with Heroku Toolbelt (heroku login).
Create a new app with heroku create.
Step 4: Configuration
Mooch authenticates requests to the Twitter API using the application-only
authentication method. This requires the consumer key and secret from the
Twitter application created in step 1.
Example authentication configuration
heroku config:set MOOCH_CONSUMER_KEY=xvz1evFS4wEEPTGEFPHBog
heroku config:set MOOCH_CONSUMER_SECRET=L8qq9PZyRg6ieKGEKhZolGC0vJWLw8iEJ88DRdyOg
Step 5: Deploy
git push heroku master
The new Mooch service should now be ready for use. Check the Heroku
dashboard for the service's location.
For more detailed configuration instructions, a demo application and more, check out the Mooch README on GitHub.