I'm trying to build an application using Angular 5 (for the client), Express (for the server) and MySQL.
There's a point in the app where I want to make an http request to the server in order to fetch some product data to use it in the app. I have a service with the following line of code:
this.http.get('http://localhost/api/?products=all')
This request returns all the products available in the database. Now how can I make sure that this request is sent from the app (in this case from that service)?
If I try http://localhost/api/?products=all for example in the browser all the data will be returned and obviously it is not wanted. So how can I authenticate these requests to the api?
Thanks...
You can use middleware function to authenticate request
function isAuthenticated(req, res, next) {
// do any checks you want to in here
// CHECK THE USER STORED IN SESSION FOR A CUSTOM VARIABLE
// you can do this however you want with whatever variables you set up
if (req.user.authenticated)
return next();
// IF A USER ISN'T LOGGED IN, THEN REDIRECT THEM SOMEWHERE
res.redirect('/');
}
Related
Backgroud :-
I have a app.post route to which data is coming from HTML page.
I want to pass contents req.body to app.get route without using query params or global variable.
query params will expose imp details and the global variable will not work if simultaneous user uses the application.
app.post('/tester', (req, res) => {
console.log(req.body.var1)
res.redirect('/Dashboard');
});
I want to pass this value to Dashboard route.
app.get('/Dashboard', (req, res) => {
//sone DB operation with values form post route and then display it dynamically
res.render('employeeDashboard',{employeeName:employeeFirstName})
}
})
}
The standard mechanism for sharing user-specific data across requests without exposing that data to the user is sessions.
The data is associated with a unique token on the server, then the token is set to the client and stored in a cookie. The client will send it back to the server on subsequent requests and the data can be retrieved from the server-side store by looking it up by the token value.
The usual way to handle this on Express is via the express-session module.
A variant of the technique which erases the data after it has been used once (so you can use it for a single redirect without it persisting beyond that) is called flash and implemented on top of sessions. The express-flash module provides this functionality.
I'm missing some sort of (most likely simple) fundamental understanding of securing a JavaScript application such as one using the VueJS framework and a service like Auth0 (or any other OAuth server/service).
1) If you create a SPA VueJS app with routes that require authentication, what stops a user from viewing your bundled code and seeing the views/templates behind that route without needing to login?
2) If you create a VueJS app that authenticates a user and sets some variable in a component like isLoggedIn = true or isAdminUser = true, what stops the user from manipulating the DOM and forcing these values to true?
All your JavaScript code is exposed to the client, so how is any of your code/content actually secure if it can be explored on the code level?
1) You understand correctly, nothing stops him. That's why you always do all that on the server side. The code in browser/VueJS is only to make the interface make sense, like hiding a button, but the server code should always do the actual check.
For example:
You have a button "Get secret document" that has a axios request behind to the path /api/sendsecret
In your VueJS app you can do something like v-if="user.isAdmin" to only show the button to the user.
There's nothing from stopping a user to find that path and just hit it manually with curl or postmaster or any other similar tool
Thats why the server code (nodeJS with express for example) should always do the checking:
app.get('api/sendsecret', (req, res) => {
if (req.user.isAdmin) {
res.send('the big secret')
} else {
res.sendStatus(401) // Unauthorized
}
})
2) Again, nothing. You should never authenticate a user in the VueJS application. Its ok to have some variables like isLoggedIn or isAdminUser to make the interface make sense but the server code should always to the actual authentication or authorization.
Another example. Lets say you're gonna save a blog post
axios.post('/api/save', {
title: 'My Blog Post'
userId: 'bergur'
}
The server should never, never read that userId and use that blindly. It should use the actual user on the request.
app.post('api/save', (req, res) => {
if (req.user.userId === 'bergur') {
database.saveBlogpost(req.body)
} else {
res.sendStatus(401)
}
})
Regarding your final marks:
All your JavaScript code is exposed to the client, so how is any of
your code/content actually secure if it can be explored on the code
level?
You are correct, its not secure. The client should have variables that help the UI make sense, but the server should never trust it and always check the actually user on the request. The client code should also never contain a password or a token (for example saving JSONWebToken in local storage).
Its always the server's job to check if the request is valid. You can see an example on the Auth0 website for NodeJS with Express.
https://auth0.com/docs/quickstart/backend/nodejs/01-authorization
// server.js
// This route doesn't need authentication
app.get('/api/public', function(req, res) {
res.json({
message: 'Hello from a public endpoint! You don\'t need to be authenticated to see this.'
});
});
// This route need authentication
app.get('/api/private', checkJwt, function(req, res) {
res.json({
message: 'Hello from a private endpoint! You need to be authenticated to see this.'
});
});
Notice the checkJwt on the private route. This is an express middleware that checks if the user access token on the request is valid.
I have a basic express application with a couple of routes and a login function, now the user has a balance associated to its data which is stored in a express-session however when the user refreshes I want the balance to update, to do this I need to get the balance again from the database and put it in the session when the user refreshes.
I just cannot seem to find out how to handle a user refreshing.. How do you do it?
I'm using PassportJS for handling login/regristrations.
Could you have a middleware function that runs for all requests which uses the users id from the session object to look up their balance from the database and then assign the updated balance to the session object?
The middleware would be like this:
app.use(function(req, res, next){
// use req.session.userId to look up balance.
// req.session.balance = lookedUpValue;
});
This should be placed before any routes in the app.
I am using angularJS and expressJS with NodeJS. I need its authorization methods to work the existing infrastructure.
For the existing infrastructure, we already have a single sign-on security application. It validates username/password and then sets a session ID in the session cookie and the database. When a user go our other applications, they check if the session ID in user browser exists in our database and if it is expired or not; if the session ID is valid, the user is allowed access.
For my new project, I plan to protect the expressJS API since it access the database. I plan to create a check session ID function that check if a session ID is valid in the database. I require every expressJS API function to have a session ID parameter and call the check session ID function on the passed in parameter. Next I plan to use cookie service in anuglarJS to access the session ID stored in session cookie and pass that to every expressJS API called in angularJS.
With my existing infrastructure, do you think this is a good solution?
As you use session, you don't need to check the session ID.
Instead, save some user profile field such as email into session, and check if profile exist in every request.
improvements:
1. Destroy and create new session after login
2. Set timeout for session, may be 30 mins
3. Disable cross domain request
4. Finally, use middleware function to check the authentication in every request
e.g.
app.use('*', function (req, res, next) {
checkAuth(req, res, next);
});
in function checkAuth, check profile in session, call next() if positive, else give response with access deny
Is there any way to restrict access to a given url/route in a Parse CloudCode application?
app.get( '/', function ( req, res )
{
res.render('home');
} );
// only allow access to this 'route' if the user making the request is an admin
app.get('/admin', function(req, res)
{
var user = Parse.User.current();
// user is always null. No way to check their user privileges.
res.render('admin');
});
The problem as I see it, there is no way to access the Parse.User.current(), or request user in main.js file. Creating and then accessing an 'isAdmin' CloudCode function from the client seems the wrong way to prevent access by unauthorised users to urls.
Thanks in advance.
I couldn't comment on your post due to my low point. But have you tried on This documentation?
Your have to use parse made middleware for its express cloud : parseExpressCookieSession and parseExpressHttpsRedirect. Then you can access user data easily with Parse.User.current() in cloud code.
You can see the sample code on Parse SDK reference #parseExpressCookieSession
USER SESSION MANAGEMENT
You can add Parse.User authentication and session management to your
Express app using the parseExpressCookieSession middleware. You just
need to call Parse.User.logIn() in Cloud Code, and this middleware
will automatically manage the user session for you.
You can use a web form to ask for the user's login credentials, and
log in the user in Cloud Code when you receive data from this form.
After you call Parse.User.logIn(), this middleware will automatically
set a cookie in the user's browser. During subsequent HTTP requests
from the same browser, this middleware will use this cookie to
automatically set the current user in Cloud Code. This will make ACLs
work properly in Cloud Code, and allow you to retrieve the entire
current user object if needed.
...