I'm having a bit of trouble figuring out how to use Waterlock. I'm working with Sails.js and Angularjs, and I'm not sure how to update user attributes on a Waterlock authenticated user in a Sails controller. Should I not write my own controller for this? Is there a standard way to update a user through an API call in Sails or Waterlock?
I found the solution in case anyone else is stuck here. You can access the authenticated user's data in req.session.user, and you will update the user through the Waterline ORM.
Here's some sample code:
module.exports = require('waterlock').actions.user({
updateCurrentUser: function(req, res) {
User.update(req.session.user.id, req.body)
.exec(function(err, changes) {
return res.json(changes);
});
}
});
Related
I'am using express-session for creating session in nodejs & using http.post method to send datas to nodejs. How to retrieve the session variable in html using angularjs? Can you please help me?
Here is my code
Inside angularjs controller in the first html page,
$http.post('/form', data)
.then(
function(response){
if (response.data) {
$window.location.href = 'other.html';
}
},
function(response){
console.log("inside failure");
}
);
In nodejs,
app.post('/form', function (req, res) {
console.log("Incoming data" , userData);
req.session.mob = userData.mob;
req.session.provider = userData.provider;
res.send(req.session.mob);
}
I have to display the mob value in the 'other.html' which is stored in nodejs session.Can you suggest me how to do it through angularjs?
Not sure If i understand your question correctly - i'll try to help.
First of all, it will be angularJs best practice to use routes or states and pass the data you received from the server (response.data in your example) as a state param or a url param to the new page, and avoid the redirection.
If you do need to redirect to the "other.html" just pass the data from the server as query param in the url (if its a property) or save it in the browser storage (local storage, if the new page is being opened in a new tab) and read the data when your other.html is loaded.
Make sure that you pass a url to $window.location.href.
I have a request, Can anyone tell me, how to properly do. I want to make two navbars in my project, first is intended for admin, second for user. I use with NodeJS (back), AngularJS (front). At the moment I created on the side NodeJS script, Which checks the status of the user role:
In router index.js (I think its good place?)
router.get('/checkRole', function (req, res) {
if (req.user != null) {
if (req.user.role == 'admin') {
res.json('admin');
}
} else {
res.json('user');
}
});
Now the question is what next?
Create Service with http.get to index route, and every time, when will be loaded page check status and load navbar?
(Important thing)
So I need in each controller to add a service (http get, check status, load navbar) yes?
Or is another way? Can someone explain me??
Sorry for english, and thanks for help.
I'm new to MEAN development, and I'm using bcrypt to encrypt the password from UserSchema (everything works wonders), but since I have to authenticate from the client side I've made a function to the UserSchema:
UserSchema.methods.comparePassword = function(candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
if (err) return cb(err);
cb(null, isMatch);
});
};
Now.. how do I call this function from the client side?
I'm using Restangular, and I'm trying something like this:
function authLogin() {
if(vm.user && vm.user.email && vm.user.password){
User.getList({ email: vm.user.email }).then(function(user){
user.comparePassword(vm.user.password, function(err, isMatch) {
if (err) throw err;
console.log(vm.user.password, isMatch);
});
});
}}
But then occurs an error saying that user doesn't have the funciton:
user.comparePassword is not a function
So, what is wrong about it? Or it is not possible to call a Schema function directly from the client side?
I believe the answer to your immediate question (if i understand which of your code samples lives to which layer): why is it "not possible to call a Schema function directly from the client side" is that the server and client side javascript run in a completely different context so functions you might declare in server-side models or middleware are not available to your client context.
The general solution to "call a schema function" from the client side with node and javascript frameworks is to POST or GET data to a server-side API endpoint and then you call your schema methods within the API code (or middleware attached to that API endpoint).
I would suggest that you take a look at the https://www.npmjs.com/package/passport passport authentication API module which is a market standard way to handle client authentication that you should be able to pretty easily bolt onto your application.
I am creating a project in AngularJs at frontend and Spring MVC in backend.
Now assume when a used logged in and if he wants to update his information, for this i have created an api which request for emailid and update the rest object in database of that email id
Now i have some questions,
1.) I dont want to use CookieStore or others sessionStorage or localstorage (because of my personal vulnerability experience and also i want to use session only) in Angular, how can i do it in angular with Spring MVC.
2.) How can i retrieve the email id from session to update data?
3.)If a user goes to another page how can i maintain that session in another page, how can i check that session is there and user is authentic to see the page
Read a lot about it but unable to find the exact solution with session. Answer over there is manage it by cookieStore.or localstorage, Please help
Let's try and see what is happening here using cookies is the right way to this, you may think it is not safe but is the safest way to do it. With cookies you will be sharing the same session in all tabs, so you can handle in all tabs and share it.
There is also an alternative option and is using URL rewriting, quoting #vanje in this question in stackoverflow
the session is only identified via a URL parameter containing the session ID. So every internal URL of your web application has to be enhanced with this parameter using the method HttpServletResponse.encodeURL(). If you are using a web framework like Wicket, chances are good that this is already done for you.
Lets go now with the Angular JS - Spring MVC approach:
There is no need to access the session within the Angular JS front-end, if you need to use it and you are using JSP you may use scriplet to retrieve the information openening a <%= session.getAttribute("user") %> , but as I said there is no need to do this. You may call your function, and retrieve this information in your controller in Spring.
You have a controller in angular JS that calls with http to your REST controller in Spring such like this. assuming that you save your user first in session:
$scope.getUserInfo= function () {
$http.get(appContextPath +'/rest/getuser/').success(function (data) {
$scope.user= data;
});
};
You may have a request mapping for the URL above:
#RequestMapping(value = "/rest/getuser", method = RequestMethod.GET)
#ResponseBody
public User getUserInfo (HttpSession session) {
User nUser = session.getAttribute("user");
return nUser;
}
I think the best way is to create a method in your AngularJS controller and then call it.
Java code:
#RequestMapping(value = "/menu/get", method = RequestMethod.GET, headers="Accept=*/*")
public #ResponseBody Empleado showMenu(HttpSession session) {
Empleado empleado = (Empleado) session.getAttribute("empleado");
return empleado;
}
AngularJS code:
angular.module('myModule')
.controller('myMenuController', ['$scope', '$http'
function($scope, $http){
getEmpleadoInfo = function () {
$http.get(myContextPage + '/menu/get')
.then(function(data) {
$scope.empleado = data;
})
}
getEmpleadoInfo();
}]);
This way, when you load the page, the object will be loaded on the scope.
I'm having much trouble getting OAuth2 to work with a generic OAuth2 provider. Here's the situation.
A service provides an OAuth2 authentication method to where I want to authorize with. I've created an AngularJS app that has the following configuration for satellizer:
authProvider.baseUrl = 'http://localhost:3030/user/authorize';
$authProvider.oauth2({
name: 'customname',
url: '/token',
clientId: 'someapp',
requiredUrlParams: ['scope'],
scope: ['profile'],
authorizationEndpoint: 'http://location.to.oathserver',
redirectUri: 'http://localhost:3000'
});
The baseUrl points to my node server that should handle the middleware part.
I've also the following code that triggers the authentication part.
$scope.authenticate = function(provider) {
$auth.authenticate(provider)
.then(function(response) {
console.log(response);
})
.catch(function() {
//something went wrong
});
}
So far this all seems to work great and looks very similar to what is documented by Satellizer! Now once I start the angular app and start the authentication I see requests coming by that target my Node service.
Next I've my node.js service that hooks to the 'user/authorize/token' URL. Here's the code:
router.options('/authorize/token', function(req, res, next) {
//var token = req.header('Authorization').split(' ')[1];
res.end();
});
and:
router.post('/authorize/token', function(req, res, next) {
var authCode = req.param('code');
var cliendId = req.param('clientId');
var payload = jwt.decode(authCode, 'mySecret');
});
Here's where it all seems to go wrong. First I seem to get an OPTIONS request. I've not really an idea what to do with it as I can't seem to find anything in the documentation about an OPTIONS request. I thought it would might contain the 'Authorization' header but that doesn't seem the case so I close the connection with a res.end();
I also inspected the request in Chrome but I can't seem to find a header that has this exact name.
Next I get a POST request. This does seem to contain some things, hooray! I get the following object:
{
code: "ZFFeat9pWfHzw4rGmjFYwucPRMFnBOkd2odEObvo",
cliendId: "someapp",
redirectiUri: "http://localhost:3000"
}
This looks to me like the authorization code that I should have to decode. That's what you see me trying as well in the code above. Unfortunately this seems to throw me an error
Error: Not enough or too many segments
This tells me I'm doing probably something wrong, and I got stuck.
I do have some PHP code that seems to work for someone else but I don't fully understand and can't really relate the code to my code since PHP is not my speciality and node.js/JavaScript not his. So here goes the PHP code:
handle_cors(); // Handle CORS for cross domain requests
// Get JSON data
$input = json_decode(file_get_contents("php://input"), true);
// Create Provider
$provider = new SomeApp\OAuth2\Client\Provider\SomeApp([
'clientId' => 'someapp',
'clientSecret' => 'mySecret',
'redirectUri' => $input['redirectUri'],
]);
// Optional: Now you have a token you can look up a users profile data
try {
// Try to get an access token (using the authorization code grant)
$token = $provider->getAccessToken('authorization_code', [
'code' => $input['code']
]);
// We got an access token, let's now get the user's details
$user = $provider->getResourceOwner($token);
header('Content-Type: application/json');
$result = $user->toArray();
$result['token'] = create_token('my-example-key', $user->getId());
echo json_encode($result);
exit();
} catch (Exception $e) {
// Failed to get user details
exit('Oh dear...' . $e->getMessage());
}
Hopefully someone can help me out! Thanks in advance.
Sorry guys, I've been able to solve it myself. I found out that I was missing some URL's to POST to and GET from. After that the examples from Satellizer became clear and was able to use them almost as a carbon copy.