Angular 2 404 error when attempting login - javascript

I have an angular 2 application which talks to a standalone backend nodejs api. Out of know where I am getting a 404 when I try to log in to my application. This just started happening and I went back to different versions of code in both front and backend to see if something in the recent code broke my app. I have verified the node backend is running by checking its existence in the activity monitor. There is absolutely no activity in the console for the backend when I try to hit the endpoint.
When I look at the network tab I am getting a 404 but the rest of the details seem to indicate that everything was sent as expected including the correct request url and request payload.
The only thing that I am not sure is normal is there seems to be two login attempts with the first one resulting in a 204. I actually do not know if this is a normal behavior.
After attempting to login I get the follow report in the network tab:
The details for both listings are below:
Any ideas would be greatly appreciated. Been wasting lots of precious time fighting with this. Thanks.
Update with some backend code per request:
The entry file is large but basically works like this:
Services and Models are instantiated and passed into the routes:
let authRouter = authCreateRouter(passport, services);
Auth Router:
module.exports = (passport, services) => {
let router = express.Router();
router.post('/login', (req, res, next) => {
passport.authenticate('login', (err, user, info) => {
if (err) {
logger.info({
err,
stack: err.stack
}, 'the error');
return next(err);
}
if (!user) {
logger.info({
user
}, 'this user could not be authenticated');
return res.status(401).json({
success: false
});
}
let token = jwt.sign({
id: user.id
}, process.env.SESSION_SECRET, {
expiresIn: '12h'
});
res.json({
success: true,
userId: user.id,
signup: user.signup,
avatarUrl: user.avatarUrl,
accountVerified: user.accountVerified,
user,
token
});
})(req, res, next);
});
};
The above code then interacts with the appropriate service. The thing is none of this code has changed so it is not likely the issue.

Related

How to track visits or clicks on an Url shortener using ExpressJS and NodeJS?

I'm working on a URL shortener for learning purposes, and I want to add a way to track the clicks or visits for each shortened URL.
An example of a shortened URL from my app is this: http://localhost:3000/384oxt where the code 384oxt is saved in my database and is related to the URL: https://www.google.com/.
So, when the user visits: http://localhost:3000/384oxt, I have this method to do the redirect:
const redirect = async (req, res) => {
const { code } = req.params;
if (!code || !(await ShortenedUrl.existsUrlCode(code))) {
return res.status(404).json({
status: 'err',
errors: [
{
message: "The urlCode doesn't exist",
},
],
});
}
try {
const shortenedUrl = await ShortenedUrl.findOne({ urlCode: code }).exec();
console.log(req);
return res.redirect(301, shortenedUrl.source);
} catch (err) {
console.error(err);
return res.status(500).json({
status: 'err',
errors: [{ message: 'A problem has occurred, please try again' }],
});
}
};
As you can see, I get the code, then I check if the code exists in the database, if not, I return a response with the message error, but if the code exists, I get from the database the URL that is linked to that code and I do the redirect.
The first time, it works OK, and this instruction: console.log(req); prints the request on the console.
But if I use the same shortened URL again: http://localhost:3000/384oxt, it seems like the browser is doing the redirect without entering the redirect method in my NodeJS app. The instruction console.log(req); is not printed anymore. Even if I delete the method, the redirect still works.
I want to store some statistics like the browser, time, etc when someone uses the shortened URL, but with this behavior, I can't.
How can I force that every time the shortener URL is used the method is executed?

Switched to promise based DB, now my login is completely broken

I can register just fine, however when I get directed to my game route I get a default Error page that's just white with [object Object] on the screen. Then I get the same in my console, [object Object] and it repeats every once in a while.
At first I thought it was something to do with socket.io, but it isn't even getting to that point. I think it might be something with passport and how I have it configured, not being setup good with the promise route I'm going, but I am at a complete loss. I don't know exactly where this error is occurring.
Here is the passport file:
/*jshint esversion: 6 */
const LocalStrategy = require('passport-local').Strategy;
const db = require('../config/db');
const bcrypt = require('bcryptjs');
let io = require('./io');
module.exports = (passport) => {
// Local Strategy login
passport.use('local-login',
new LocalStrategy((username, password, done) => {
console.log('username');
// Match Username
let sql = 'SELECT * FROM users WHERE username = ?';
db.query(sql, [username]).then(results => {
if (!results.length) {
return done(null, false, {
type: 'loginMessage',
message: 'Wrong Login',
});
}
console.log('password');
// Match Password
bcrypt.compare(password, results[0].password, (err, isMatch) => {
if (isMatch) {
console.log('Password is correct');
return done(null, results[0]);
} else {
return done(null, false, {
type: 'loginMessage',
message: 'Wrong Login',
});
}
});
});
}));
// =========================================================================
// passport session setup ==================================================
// =========================================================================
// used to serialize the user for the session
passport.serializeUser((user, done) => {
console.log(user.username + ' has been Serialized');
done(null, user.id);
});
// used to deserialize the user
passport.deserializeUser((id, done) => {
db.query('SELECT * FROM users WHERE id = ?', [id]).then(results => {
console.log(results[0].username + ' has been deserialized');
done(results[0]);
});
});
};
This seems to go off without a hitch, now here is my login redirect:
// Login Process
router.post('/login',
passport.authenticate('local-login', {
successRedirect: '/game',
failureRedirect: '/',
failureFlash: true,
}), (req, res) => {
console.log('login route test');
});
Again this seems to be doing well, it does in fact redirect me as intended. Now, here is some extra stuff I think might be causing it:
// Passport config
require('./config/passport')(passport);
app.use(passport.initialize());
app.use(passport.session());
app.get('*', function (req, res, next) {
res.locals.user = req.user || null;
next();
});
Then the game route:
//Route to game app
app.get('/game', function (req, res) {
console.log('Log before it checks req.user');
if (req.user) {
console.log('req.user is working');
res.render('game');
} else {
req.flash('error', 'You need to be signed in!');
res.redirect('/');
}
});
So here is the thing here: When I am not logged in and go to the /game route it will kick me back into my main route with the correct flash error. However, when I login, I can;t for the life of me get it to fire off a console.log() function. So I am thinking it is getting stuck with the req.user on login, but I am not sure why nor how. If more information is needed, I can give more... but this is mostly what all handles the login process (except socket.io, but it doesn't even get to that point yet, and all my socket.io file does is send the data client side for easy updates).
I will keep trying my luck, but since I am new to promises, this may be the reason why, and if it is, I may not be so lucky.
EDIT: Well, I've changed everything back to a normal callback for my DB (which is what I had it before). Weirdly though, I am getting the same result, and I've no idea why. This project had been put on hold for months, but I hadn't touched anything until I changed all the DB stuff. So something must have broken before I even touched anything when I left this project it was working just fine. But I did change it back to the promise method, because I'd rather stick to this message.
EDIT: Also, I am getting a 500 internal server error on the browser console.
EDIT: Updated code and added console.logs in more places to see where this is hanging up, and I'm still not sure. So here is the logging sequence when I click the login button:
username
password
Password is correct
Bloodmorphed has been Serialized
Bloodmorphed has been deserialized
[object Object]
Bloodmorphed has been deserialized
[object Object]
EDIT: So it seems like the login process is not working correctly. I am not sure why and I can't find a problem with anything I am doing. I have looked at multiple sources of how to set-up passport for MySQL and while some of them differ a tiny bit, they all seem to be the same where it matters. I do not know why this is happening and according to multiple sources of working logins, I am doing this right.
I am, well... simply an idiot. I forgot when I changed to a promise system, I handle errors inside the query itself, so there was no reason for me to pass it through.
so where I had done done(results[0]) in the passport.deserializeUser... I just had to add null before it like so: done(null, results[0]) so much wasted time on a simple matter. I feel like a dumby.

Error: Can't set headers after they are sent Node.js and ExpressJS

I am using Node.js and ExpressJS to save a mongoose model. I am getting the error of Error: Can't set headers after they are sent. I think it has to do with the line res.redirect("/dashboard/it/model"); conflicting with setRedirect({auth: '/login'}), from my route, the code in the setRedirect is below labeled. The setRedirect is from a middleware called middleware-responder that came as part of the template I am using to create Stripe user accounts. I can not remove it as far as I know. my GitHub repo I have committed all files that are not test files and are relevant (no unneeded views ect than what is already there)
Save Model
if(type=="aps"){
var newAccessPoint = {
name: name,
manufacturer: manufacturer,
model: model,
range: range,
bands: bands,
channel: channel,
poe: poe,
notes: notes,
signout: signout,
author:author
};
// Create a new access point and save to DB
AP.create(newAccessPoint, function(err, newlyCreated){
if(err){
console.log(err);
} else {
//redirect back to models page
res.redirect("/dashboard/it/model");
}
});
}
Route
app.post('/dashboard/it/model/new',
setRender('dashboard/it/modelCreate'),
setRedirect({auth: '/login'}),
isAuthenticated,
dashboard.getDefault,
(req, res) => {
setRedirect code
exports.setRedirect = function(options){
return function(req, res, next){
if(req.redirect){
req.redirect = _.merge(req.redirect, options);
} else {
req.redirect = options;
}
next();
};
};
setRender code
exports.setRender = function(view){
return function(req, res, next){
req.render = view;
next();
};
};
That's happening because you are trying to send a response to the client when you already closed the connection.
Hard to tell by the way you are showing us your code but it seems like you are redirecting to options and then in the same request you are redirecting to dashboard/it/model
I pull your code from github.
I think the error message was clear. in your getDefault() middleware you are rendering a response so the server start sending data to your client and just after you try to redirect him to another url. Thats why when your comment out that middleware all work nicely.

Getting 404 (not found) error for routes defined in config/routes.js

Just learning sails with node and have been running into an issue, I have all of my views created and my user controller, but when I click sign up, it takes me to localhost/signup and 404s me. Alternatively, going to /user, /login, /quiz all end in 404s as well.
This is my views folder contents:
- 403.ejs
- 404.ejs
- 500.ejs
- homepage.ejs
- index.ejs
- layout.ejs
- quiz.ejs
My signup method should be routing me to quiz.ejs, but just kind of breaks. These are my custom routes:
module.exports.routes = {
// HTML Views
'/': { view: 'index' },
'/quiz': { view: 'quiz' },
// Endpoints
'post /login': 'UserController.login',
'post /signup': 'UserController.signup',
'/logout': 'UserController.logout',
};
These routes are referencing my UserController.js which have a login, logout and signup function, here are those functions, here is my sign up function:
signup: function (req, res) {
// Attempt to signup a user using the provided parameters
User.signup({
name: req.param('name'),
email: req.param('email'),
password: req.param('password'),
avatar: req.param('avatar'),
}, function (err, user) {
// res.negotiate() will determine if this is a validation error
// or some kind of unexpected server error, then call `res.badRequest()`
// or `res.serverError()` accordingly.
if (err) return res.negotiate(err);
// Go ahead and log this user in as well.
// We do this by "remembering" the user in the session.
// Subsequent requests from this user agent will have `req.session.me` set.
req.session.me = user.id;
req.session.name = user.name;
// If this is not an HTML-wanting browser, e.g. AJAX/sockets/cURL/etc.,
// send a 200 response letting the user agent know the signup was successful.
if (req.wantsJSON) {
return res.ok('Signup successful!');
}
// Otherwise if this is an HTML-wanting browser, redirect to /welcome.
return res.redirect('/quiz');
});
}
As you can see, my return is set to /quiz, but it doesn't seem to fire. Edit: on click, I am receiving this console error as well:
POST http://localhost:1337/signup 404 (Not Found)
What could be causing this?
After some fiddling and looking over my files, I realized that Sublime did not save my changes to the file name. I was trying to reference UserController.js when it was actually named usercontroller.js, changing this got everything working smoothly again!

Authenticating node API with passport-jwt

I'm trying to setup JWT authentication using passport-jwt. I think I've taken the right steps, but a test GET won't succeed and I don't know how to debug it.
Here's what I've done:
setup passport-jwt straight out of the doc as much as possible
var jwtOptions = {
secretOrKey: 'secret',
issuer: "accounts.examplesoft.com", // wasn't sure what this was, so i left as defaulted in the doc
audience: "yoursite.net" // wasn't sure what this was, so i left as defaulted in the doc
};
jwtOptions.jwtFromRequest = ExtractJwt.fromAuthHeader();
passport.use(new JwtStrategy(jwtOptions, function(jwt_payload, done) {
User.findOne({id: jwt_payload.sub}, function(err, user) {
if (err) {
return done(err, false);
}
if (user) {
done(null, user);
} else {
done(null, false);
// or you could create a new account
}
});
}));
Added a token result to my user /login endpoint
var jwt = require('jsonwebtoken');
// ...
exports.postLogin = function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) throw err;
if (!user) {
return res.send({ msg: 'Login incorrect' });
}
req.logIn(user, function(err) {
if (err) throw err;
var secretOrKey = jwtOptions.secretOrKey;
var token = jwt.sign(user, secretOrKey, {
expiresIn: 631139040 // 20 years in seconds
});
res.send({ user: user, jwtToken: "JWT " + token });
});
})(req, res, next);
};
Things were looking good up to here. I can login a user (using passport local auth) and the response was a I hoped...
{
"user": {
"_id": "56c8b5bd80d16ef41ec705dd",
"email": "peachy#keen.com",
"password": "$2a$10$zd ... etc.",
"__v": 0,
},
"jwtToken": "JWT eyJ0eXAiOiJ .... etc." }
I created an unprotected test route like this...
// in my routes file
app.get('/user/tokenTest', user.tokenTest);
And in my controller, a simple endpoint...
exports.tokenTest = function(req, res) {
console.log(req.headers);
res.send("token test!!");
};
And GET-ing that works fine, too.
But then I try to protect that route like this:
app.get('/user/tokenTest', passport.authenticate('jwt', { session: false }),
user.tokenTest);
After I do that, nothing but sadness. I send a request like this:
curl -k 'https://localhost:3443/user/tokenTest' -H 'Authorization: JWT eyJ0eXAiOiJ... etc.'
And always, always get a 401:
Unauthorized
Console logs in the controller don't seem to execute, neither does logging in the passport.use strategy method. I've tweaked and tweaked, but I'm a little lost. The passport-jwt doc just supplies the example, and virtually no other help.
Please, any ideas about either a mistake that I'm making above, or at least how to go about debugging??
For any poor soul that follows me here: the passport-jwt doc implies that the auth header should look like this...
Authorization: JWT JSON_WEB_TOKEN_STRING.....
That turned out to be misleading (for me, anyway).
Fortunately, thanks to this article I was able to learn how the token is built. (The token's prefix up to the first '.' is the base64 encoding of the scheme. That "JWT " at the front was noise that prevented the validation from working.
So the fix was to change the token returned by the user controller from:
res.send({ user: user, jwtToken: "JWT " + token });
To the simpler:
res.send({ user: user, jwtToken: token });
Phew. Is it me, or is it really a bummer how inadequately these things are explained in so many node package docs??
I may be late but I had a similar problem, and I have another solution. You can use this options.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme('JWT') to extract the JWT token from authentication header with the following format:
Authorization: JWT JSON_WEB_TOKEN_STRING.....
Here is the documentation I used: https://github.com/themikenicholson/passport-jwt
Extracting the JWT from the request
There are a number of ways the JWT may be included in a request. In
order to remain as flexible as possible the JWT is parsed from the
request by a user-supplied callback passed in as the jwtFromRequest
parameter. This callback, from now on referred to as an extractor,
accepts a request object as an argument and returns the encoded JWT
string or null. Included extractors
A number of extractor factory functions are provided in
passport-jwt.ExtractJwt. These factory functions return a new
extractor configured with the given parameters.
fromHeader(header_name) creates a new extractor that looks for the JWT in the given http header
fromBodyField(field_name) creates a new extractor that looks for the JWT in the given body field. You must have a body parser configured in order to use this method.
fromUrlQueryParameter(param_name) creates a new extractor that looks for the JWT in the given URL query parameter.
fromAuthHeaderWithScheme(auth_scheme) creates a new extractor that looks for the JWT in the authorization header, expecting the scheme to match auth_scheme.
fromAuthHeaderAsBearerToken() creates a new extractor that looks for the JWT in the authorization header with the scheme 'bearer'
fromExtractors([array of extractor functions]) creates a new extractor using an array of extractors provided. Each extractor is attempted in order until one returns a token.

Categories

Resources