passport.js auth0 strategy Cross rigin request error - angularjs

I am trying to use auth0 for social validation in my web app
i configured the app like this
auth0 : {
domain : "mydomain",
clientID : "myid",
clientSecret: "mysecret",
callbackURL: "/callback"
},
I request login from angular controller using http get to node backend like
app.get('/auth/:connection', function(req, res, next) {
passport.authenticate('auth0', {connection: req.params.connection}, function(err, user, info) {
}) (req, res, next);
});
I will call like auth/facebook for facebook login from angular client side controller.
The callback route is configured like this
app.get('/callback', passport.authenticate('auth0', { failureRedirect: '#!/authServiceImpl/login' }),
function(req, res) {
console.log('auth0 callback');
console.log(req.user);
}
);
Every time I am getting Cross origin request error.
What I am doing wrong ?

I request login from angular controller using http get to node backend like
You cannot perform OAuth over XHR. Instead of doing $http.get('/auth/whatever') you'd need to do window.location.pathname = '/auth/whatever' or window.open('/auth/whatever')

Related

Authorization Error || Error 400: redirect_uri_mismatch

this error keeps showing I don't why ! I changed the URI many times and it still showing
This what my Google Cloud Console looks like:
My auth.js:
router.get('/google', passport.authenticate('google', { scope: ['profile'] }))
router.get('/google/callback', passport.authenticate('google',
{ failureRedirect: '/register' }),
(req, res) => {
res.redirect('/');
}
)
And in the PassportJs function I entered "/auth/google/callback" to callbackURL:
The route is app.use("/api/auth", authRoute); and I'm using two ports one for client (3000) and one for API (4000), now in Authorized redirect URIs which port should I use !!

Session and Login User data with Node and AngularJS

I need to know that if my authentication and session management method is right.
I am using session management as when I receive successful auth. from node server. I store user data(without any trace of pass.) in $window.sessionStorage and if user marked rememberMe(checkbox), store data in $window.localStorage too.
Through this I am able to get data in different controllers. Though I read somewhere about session implementation at server(nodeJs) side is also possible. But I am not sure about how to use session along with JSONToken Authentication.
I was using
https://jasonwatmore.com/post/2015/12/09/MEAN-Stack-User-Registration-and-Login-Example.aspx
as a learning example but I could not understand it.
/app/app.js
Why is it in the run() method ?
// add JWT token as default auth header
$http.defaults.headers.common['Authorization'] = 'Bearer ' + $window.jwtToken;
and what is this:
// manually bootstrap angular after the JWT token is retrieved from the server
$(function () {
// get JWT token from server
$.get('/app/token', function (token) {
window.jwtToken = token;
angular.bootstrap(document, ['app']);
});
});
/controllers/app.controller.js
// use session auth to secure the angular app files
router.use('/', function (req, res, next) {
if (req.path !== '/login' && !req.session.token) {
return res.redirect('/login?returnUrl=' + encodeURIComponent('/app' + req.path));
}
next();
});
// make JWT token available to angular app
router.get('/token', function (req, res) {
res.send(req.session.token);
});
// serve angular app files from the '/app' route
router.use('/', express.static('app'));
So using a session server-side with JWT kind of defeats the purpose of using JWT. JWT's are awesome in a number of ways, but one of the ways they are great, is regardless which server intercepts a request, they can verify the user.
If you put it in a session, you have to make sure the client keeps going to the same server as the session is saved in memory on that machine. There are plenty of ways around that, but again it kind of defeats the purpose of a JSON web token.
What I did for my authentication with angular/node/JWT was just passed the JWT back in the header every time, and with my middleware intercepted it with:
req.header.whatever_my_tokens_name_is
The code below set the $http to send on every request the JWT Token to the server.
// add JWT token as default auth header
$http.defaults.headers.common['Authorization'] = 'Bearer ' + $window.jwtToken;
The code below get the token from '/app/token' and store it in LocalStorage. After that, it starts the angular.
// manually bootstrap angular after the JWT token is retrieved from the server
$(function () {
// get JWT token from server
$.get('/app/token', function (token) {
window.jwtToken = token;
angular.bootstrap(document, ['app']);
});
});
Here this is a middleware that check if there are no token stored in req.session.token and requested url is not '/login'. If so, send a redirect to '/login'.
// use session auth to secure the angular app files
router.use('/', function (req, res, next) {
if (req.path !== '/login' && !req.session.token) {
return res.redirect('/login?returnUrl=' + encodeURIComponent('/app' + req.path));
}
next();
});
Finally here, this is a endpoint to the client request the '/token' again from the server.
// make JWT token available to angular app
router.get('/token', function (req, res) {
res.send(req.session.token);
});
Anyway, check the #morgan-g response regarless session-side and JWT.
I hope this helps.

Angular authentication using Passport for Ionic App

I've built an API for my web app, which is built using MEAN stack.
Now I am trying to use this API on mobile client side which is built using Ionic Framework.
I'm using this code to perform an $http call to API:
$http.post(ServerIP+'/login', {username: $scope.credentials.username, password: $scope.credentials.password}).success(function(response) {
$scope.authentication.user = response;
$location.path('/');
}).error(function(response) {
$scope.error = response.message;
});
It gets a valid response with user object, but if I try to get some info from protected parts of an API it doesn't work and auth is being reset.
On web app, I use the same code and everything works fine.
This issue happens only on Ionic app.
I've set the CORS like that:
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
// intercept OPTIONS method
if ('OPTIONS' === req.method) {
res.sendStatus(200);
}
else {
next();
}
});
Please, help me!
Try adding this line in your angular config:
app.config(function ($httpProvider) {
$httpProvider.defaults.withCredentials = true;
});
I've solved this problem by adding Token-Based Authentication.
Here's the article which shows how to do that: https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/
Sample of my "login" route:
router.post('/login', passport.authenticate('local'), function(req, res, next){
if (req.user) {
var token = jwt.sign(req.user, secret, {expireInMinutes: 60*24*7});
res.json(token);
};
});
For getting user object on protected routes, I'm using expressJwt({secret: secret}) middleware.

Login by facebook in angular app with loopback backend

I'm making an angular application with strongloop loopback backend.
Also I integrating a third party login by facebook using loopback-passport module.
everything was fine in loopback-example-passport and everything is fine in my app right before the moment of redirecting to my app. User and Access-token created.
the code:
app.get('/auth/login', ensureLoggedIn('/#login'), function(req, res, next) {
console.log('LOOGED IN!!');
console.log(req.user);
res.redirect('/#auth/login');
});
works fine. But i can't understand. how to give authenticated state to my angular application.
i tried to make a controller to route '/#auth/login':
.controller('AuthCalbackCtrl', function($scope, $cookies, $location, AppAuth, $http, User, LoopBackAuth) {
//analogue of User.login responce interceptor
LoopBackAuth.currentUserId = $cookies['userId'] || null;
LoopBackAuth.accessTokenId = $cookies['access-token'] || '';
LoopBackAuth.rememberMe = false;
LoopBackAuth.save();
//asking for currentUser
User.getCurrent(function(user) {
console.log('ser.getCurrent ', user);
});
$location.path('/');
})
This code makes a request GET /api/users/2 but receives 401 error.
If I tweak the file /loopback/lob/models/user.js setting permission:
principalType: ACL.ROLE,
// principalId: Role.OWNER,
principalId: Role.EVERYONE,
permission: ACL.ALLOW,
property: "findById"
Then the request GET /api/users/2 receives 200 and everything ok.
I'm a little confused. I can`t understand how to make my angular app authenticate to loopback, although i know access-token and userId
Have anybody any ideas how to do it?
Here is a valid code.
app.get('/auth/login', function(req, res, next) {
//workaround for loopback-password
//without this angular-loopback would make incorrect authorization header
res.cookie('access-token', req.signedCookies['access-token']);
res.cookie('userId', req.user.id);
res.redirect('/#auth/login');
});
The problem is that loopback-passport signs cookie:
res.cookie('access-token', info.accessToken.id, { signed: true,
maxAge: info.accessToken.ttl });
In string it looks something like the following "s:.eBvo8bpo9Q9wnNrPjjlG%2FAcYqWkxEgNFqn%2FO54rdGwY"
But loopback-angular just copies the access-token to header.authorization, so we need to put there plain cookie.

Authentication when using angularjs and passportjs

I am currently using passportjs for authenticaton.
I have come across a stage where i need to ensure the user is authenticated if the url is typed in the browser/ I have been using the passportja example which has the following:
app.get('/admin', ensureAuthenticated, function(req, res){
console.log('get admin');
res.render('admin', { user: req.user });
});
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) { return next(); }
res.redirect('/login')
}
I am using angularjs for routing so my get does not work and run the ensure authenticated.
How should this be implemented?
With AngularJS, you need to restrict the display of templates to the user.
So, let us say you have the following code in AngularJS:
$routeProvider.when('/admin', {
templateUrl: '/partials/admin-page.html'
});
When the user tries the /admin route, AngularJS will then request the template /partials/admin-page.html.
Thus, in your nodeJs server, you then implement the following code:
app.get('/partials/admin-page.html', ensureAuthenticated, function (req, res) {
res.render('admin', { user: req.user});
});

Resources