Satellizer.Js is not sending the Authorization header to the server - javascript

Problem: Satellizer is not sending the Authorization Header to server.
I am trying out Satellizer.Js on a project that I am working on. It's great so far, however, it is not properly sending the Authorization Header in the request to the server (Note: I am using Node for the backend). It's not a CORS problem, since I'm working with localhost for the time being. When I locally log in/sign up, the server responds with a token, and Satellizer correctly sets that in local storage. I check the Network tab in the dev tools to check the headers, but no Authorization header. Has anyone dealt with this, or have any ideas/tips I can use? Thanks in advance.
Here is my server.js code:
var express = require('express'),
app = express(),
path = require('path'),
cors = require('cors'),
bodyParser = require('body-parser'),
mongoose = require('mongoose'),
config = require('./config/config'),
morgan = require('morgan'),
port = process.env.PORT || 8080;
var express = require('express'),
app = express(),
path = require('path'),
cors = require('cors'),
bodyParser = require('body-parser'),
mongoose = require('mongoose'),
config = require('./config/config'),
morgan = require('morgan'),
port = process.env.PORT || 8080;
//connect to the database
mongoose.connect(config.db);
//morgan - log all requests to the console
app.use(morgan('dev'));
//middleware for body parser
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());
//handle CORS requests
app.use(cors());
/*app.use(function(req,res,next){
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With, content-type, \ Authorization');
next();
});*/
//set the location for static files
app.use(express.static(__dirname + '/public'));
//API Routes
var apiRoutes = require('./app/routes/app-routes.js')(app,express);
app.use('/auth', apiRoutes);
//send the users to the front end
app.get('*', function(req,res){
res.sendFile(path.join(__dirname + '/public/app/views/index.html'));
});
//listen on port
app.listen(port, function(){
console.log('Listening on port: ' + port + "....");
});
Here is where to token gets set on the angular side with satellizer:
vm.login = function(){
$auth.login({email: vm.user.email, password: vm.user.password})
.then(function(res){
//check for token;
if(!res.data.token){
vm.error = true;
vm.errorMessage = res.data.message;
}else{
//redirect to the dashboard
$location.path('/dashboard');
}
})
.catch(function(){
vm.error = true;
vm.errorMessage = "Failed to login, please try again."
});
};
Here is my only authenticated route:
router.get('/dashboard', ensureAuthenticated, function(req,res){
//with a validated token
console.log(req.headers);
console.log(req.headers.authorization);
res.json({success: true, message:'You made it, congrats!'});
});
This is my create-a-token function, and this is my authentication middleware:
function createToken(user){
var payload = {
exp: moment().add(14, 'days').unix,
iat: moment().unix(),
sub: user._id
}
return jwt.encode(payload,config.secret);
};
function ensureAuthenticated(req, res, next) {
if (!req.headers.authorization) {
return res.status(401).send({ message: 'Please make sure your request has an Authorization header' });
}
var token = req.headers.authorization.split(' ')[1];
var payload = null;
try {
payload = jwt.decode(token, config.secret);
}
catch (err) {
return res.status(401).send({ message: err.message });
}
if (payload.exp <= moment().unix()) {
return res.status(401).send({ message: 'Token has expired' });
}
req.user = payload.sub;
next();
}
Note: Satellizer.Js 's $httpInterceptor is responsible for sending the token in the request. Here is that code:
.factory('SatellizerInterceptor', [
'$q',
'SatellizerConfig',
'SatellizerStorage',
'SatellizerShared',
function($q, config, storage, shared) {
return {
request: function(request) {
if (request.skipAuthorization) {
return request;
}
if (shared.isAuthenticated() && config.httpInterceptor(request)) {
var tokenName = config.tokenPrefix ? config.tokenPrefix + '_' + config.tokenName : config.tokenName;
var token = storage.get(tokenName);
if (config.authHeader && config.authToken) {
token = config.authToken + ' ' + token;
}
request.headers[config.authHeader] = token;
}
return request;
},
responseError: function(response) {
return $q.reject(response);
}
};
}])
.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push('SatellizerInterceptor');
}]);

Try setting the Authorization header like this...
request.headers.Authorization = token;

What's your motivation behind setting token manually with $auth.setToken when Satellizer takes care of it automatically when $auth.login is used?
Here is Satellizer login example which works perfectly in our apps:
angular.module('MyApp')
.controller('LoginCtrl', function($scope, $location, $auth, toastr) {
$scope.login = function() {
$auth.login($scope.user)
.then(function() {
toastr.success('You have successfully signed in!');
$location.path('/');
})
.catch(function(error) {
toastr.error(error);
});
};
});
Bottom line: you shouldn't set token yourself. Satellizer does it automatically behind the scenes.

I had the same problem. You must send all requests with "/api/" prefix. Without this prefix I got error, but w

Related

express-jwt authentication middleware not working

I'm using express-jwt for athentication, and the following is my code:
api>routes/index.js:
var express = require('express');
var router = express.Router();
var jwt = require('express-jwt');
var auth = jwt({ secret: 'thisIsSecret', requestProperty: 'auth' });
after this inside index.js when i use auth middleware in
router.post('/locations/:locationId/reviews', auth, ctrlReviews.reviewsCreate);
route, when want to post reviews data with post-man, request goes to loading, and no response appear, but if remove auth from route request give response.
I have also checked with
var auth = jwt({
secret: process.env.JWT_SECRET,
userProperty: 'payload'
});
As mentioned in the comments, you're trying to handle valid and invalid tokens. This should be possible with something similar to the below code.
If you use Postman to call this with the following header, then you'll receive 200 OK, with a message of 'OK!'.
Authorization: Bearer validJWT
If you use Postman to call this without a valid JWT then you'll receive 401 Unauthorized with a message of 'invalid token...'.
var jsonwebtoken = require('jsonwebtoken');
var express = require('express');
var app = express();
var jwt = require('express-jwt');
var auth = jwt({ secret: 'thisIsSecret', requestProperty: 'auth'});
// Generate valid JWT
console.log(jsonwebtoken.sign({ foo: 'bar' }, 'thisIsSecret'));
app.post('/locations/:locationId/reviews', auth, function(req, res, next) {
// Log user details set in JWT
console.log(req.auth)
res.send('OK!');
});
// Handle invalid JWT
app.use(function(err, req, res, next) {
if (err.constructor.name === 'UnauthorizedError') {
res.status(401).send('invalid token...');
}
});
app.listen(3000, function() {
console.log('Server running on 3000')
})

How to get JWT token from Express to Angular using ngResource?

I am working with a jwt token to validate user registration. A unique url is sent to user's email and it redirects to the authentication page, the token is decoded on server side and I need to send this json data to angular, on client side. How can I do this using token as query parameter and retrieve it using ngResource?
server.js
'use strict';
var express = require('express');
var app = express();
var router = express.Router();
var bodyParser = require('body-parser');
var nodemailer = require('nodemailer');
var jwt = require('jsonwebtoken');
var moment = require('moment');
var port = process.env.PORT || 5000;
app.use(express.static('./src/client/'));
app.use(express.static('./'));
app.use(express.static('./.tmp'));
app.use('/*', express.static('./src/client/index.html'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// sign with default (HMAC SHA256)
var expires = moment().add(12, 'hours').valueOf();
var token = jwt.sign({
user: 'userdata',
iat: Math.floor(Date.now() / 1000),
expireIn: expires
}, 'thisismysecretstring');
// nodemailer sendMail function
app.post('/sendMail', function(req, res) {
var transporter = nodemailer.createTransport('smtp://b204bf8f6ede15:71b5c1473852e2#mailtrap.io:2525');
var data = req.body;
var mailOptions = {
from: 'noreply#ixfire.com',
to: data.email,
subject: 'Email sent by ' + data.displayName,
html: '<p>Please click on url below to register</p><br>CLICK HERE'
};
transporter.sendMail(mailOptions, function(error, info) {
if (error) {
return console.log(error);
}
console.log('Message sent: ' + info.response);
});
res.json(token);
});
// decode token from url parameter
app.get('/auth', function(req, res) {
var token = req.query.token;
try {
var decoded = jwt.verify(token, 'thisismysecretstring');
if (decoded.exp <= Date.now()) {
res.end('Access token has expired', 400);
}
res.json(decoded);
} catch (err) {
console.log(err);
res.json(err);
}
});
// router.use(function(req, res, next) {
// var token = req.query.token;
// try {
// var decoded = jwt.verify(token, 'thisismysecretstring');
// res.json(decoded);
// } catch (err) {
// console.log(err);
// res.json(err);
// }
// });
// app.use('/auth', router);
app.listen(port, function () {
console.log('Express app listening on port: ' + port);
console.log(__dirname);
});
token.js
(function() {
'use strict';
angular
.module('xfire.token', ['ngResource'])
.factory('Token', function($resource) {
return $resource('auth/:token', {
token: '#token'
});
});
})();
url format:
http://localhost:3000/auth/?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiZ2NmYWJyaSIsImlhdCI6MTQ2ODI0NDI1NCwiZXhwaXJlSW4iOjIxNjAwMDAwfQ.5rs1rlWMTTcap4idG-XOU-UiwbU0YzlnAYjm9Vwz-B0
I usually send it in a header, most often I name it x-auth-header.
I don't however use nor I recommend anyone (except for playing around) to use ngResource, as it is limiting.
Personally, I use restangular, with request/response interceptors.
Response interceptor to grab and decode the token, and request interceptor to authorize the request with "Bearer" + tokenString.

Can't achieve CORS with Express.js

I'm making a PATCH request from a client running on localhost:3000 with the following code:
axios.patch(
"http://localhost:3090/v1/users/etc/etc/etc", {
name,
url,
}, {
headers: {
authorization: AUTH_TOKEN()
}
}
)
To a server configured as follows:
var app = express();
var cors = require('cors');
//etc
//var whitelist = [
// 'http://localhost:3000',
// 'localhost:3000'
//];
//passing this to cors() doesn't help
//var globalCorsOptions = {
// origin: function(origin, callback) {
// callback(null, whitelist.indexOf(origin) !== -1);
// }
//};
app.use(morgan('combined'));
app.use(cors());
app.options('*', cors());
app.use(bodyParser.json({type:'*/*'}));
app.use('/v1', router);
var port = process.env.PORT || 3090;
var ip = process.env.IP || 'localhost';
var server = http.createServer(app);
server.listen(port, ip);
But the request just hangs. I can do POST/GET fine, but not DELETE/PATCH. The preflight happens fine but the actual request following just sits "stalled" indefinitely. Here's the headers for each request:
Sorry to ask this pretty standard question, but I've tried everything.
EDIT:
Added the following to router (still not working):
var router = express.Router();
router.use(function(req, res, next) {
res.header("Access-Control-Allow-Headers", "PATCH,DELETE,OPTIONS,GET,POST");
next();
});
The actual error:
On the server you have to add following header to the response:
headers.Add("Access-Control-Allow-Headers", "PATCH,DELETE,GET,POST");
Actually all HTTP methods you want to allow.

Can't access cookie on http in Heroku only https

I am having a strange issue with cookies in my node app. It is hosted on Heroku and I use JSON Web Tokens stored in a cookie that is authenticated by my express middleware. When I login on my Macbook pro, the cookie is successfully stored. However, when I use Linux Mint desktop, or an Android tablet, the site logs in but then redirects on protected routes and the cookie is never set.
This is where the cookie is set on login:
let token = jwt.sign({
username: user.username,
email: user.email
}, config.privateKey, {
expiresIn: '7d'
});
let userResponse = {
success: true,
message: 'Successfully logged in!',
id: user._id,
email: user.email,
username: user.username
}
// set cookie for 7 days
res.cookie('auth_token',
token,
{maxAge: 604800000, path: "/"}).json(userResponse);
Here is my server.js file:
'use strict';
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const env = process.env.NODE_ENV || "development";
const mongoose = require('mongoose');
const cookieParser = require('cookie-parser');
const config = require('./app/config/config.js');
process.env.PWD = process.cwd();
// Establish connection with MongoDB
mongoose.connect(config.db.connectString);
app.use(cookieParser());
// Allowing X-domain request
var allowCrossDomain = function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Cache-Control");
// intercept OPTIONS method
if ('OPTIONS' == req.method) {
res.send(200);
}
else {
next();
}
};
app.use(allowCrossDomain);
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static('public'));
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error: '));
db.once('open', () => {
console.log('Connected to sondage database');
});
// ===== Import Routers ======
const userRouter = require('./app/routes/user.routes')(express, app);
const pollRouter = require('./app/routes/poll.routes')(express, app);
const authRouter = require('./app/routes/auth.routes')(express, app);
app.use('/api/users', userRouter);
app.use('/api/polls', pollRouter);
app.use('/api/', authRouter);
// For all other requests, use React Router
app.get('*', function (request, response){
response.sendFile(process.env.PWD + '/public/index.html');
});
app.listen(process.env.PORT || 3000, () => {
console.log('Server running');
});
EDIT I have traced this down to a http vs https issue. If I use https in the request, the cookies work. Otherwise cookies aren't set. So I need a way to force the user to do HTTPS.
I was able to fix this using the heroku-ssl-redirect node package. This takes requests and forces the browser to use https for each request.

Middleware error in geting handshake session Node.js

I am having problems with Middleware to get the handshake.session in socket.io module to work properly with even a simple example.
1.- I have some error in the cod
how can be solved
2.- please just need
get handshake session
Thanks
I am just trying to get this example to work:
const KEY = 'express.sid'
, SECRET = 'express';
var express = require('express'), app = express()
, server = require('http').createServer(app)
, io = require('socket.io').listen(server)
, cookie = express.cookieParser(SECRET)
, store = new express.session.MemoryStore()
, session = express.session({secret: SECRET, key: KEY, store: store});
app.configure(function(){
app.set('view engine', 'ejs');
app.use(cookie);
app.use(session);
});
app.get("/", function(req, res){req.session.ID = "U"+2;});
server.listen(3000);
io.set('authorization', function(data, accept) {
cookie(data, {}, function(err) {
if (!err) {
var sessionID = data.signedCookies[KEY];
store.get(sessionID, function(err, session) {
if (err || !session) {
accept(null, false);
} else {
data.session = session;
accept(null, true);
}
});
} else {
accept(null, false);
}
});
});
io.sockets.on('connection', function (socket) {
var session = socket.handshake.session, id = session.ID;
console.log(id);
});

Categories

Resources