passport-jwt, not throing error, but not authenticating. wont even console.log - express

I am trying to authenticate using passport-jwt, express etc.
I currently am not getting authenticated, but most troubling is that I cant seem to console.log inside the function... nothing happens.
Here is the full passport.js
const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const User = require('../models/user');
const config = require('../config/database');
module.exports = function(passport) {
let opts = {};
opts.jwtFromRequest = ExtractJwt.fromHeader();
opts.secretOrKey = config.secret;
console.log(opts); // THIS SHOW PRIORE TO THE EXPRESS LISTEN MSG!
passport.use(new JwtStrategy(opts, (jwt_payload, done) => {
console.log(jwt_payload); // THIS DOESNT EVER SHOW!
User.getUserById(jwt_payload._id, (err, user) => {
if (err) {
return done(err, false);
}
if (user) {
return done(null, user);
} else {
return done(null, false);
// or create a new account
}
});
}));
}
the users.js
const express = require('express');
const router = express.Router();
const passport = require('passport');
const jwt = require('jsonwebtoken');
const config = require('../config/database');
const User = require('../models/user');
...code removed for brevity...
router.get('/profile', passport.authenticate('jwt', {session:false}), (req,res,next) => {
res.json({user: req.user});
});
module.exports = router;
Any ideas on how I can 'see' my payload so I can find whats going on?
Im using postman to hit 'http://localhost:3000/users/profile'
passing headers "authentication" and the token "JWT my-token..."
THx - I realize this is a bit of an odd request...The tutorial I was following, indicates I should be able to see the payload, even if i am not authenticated...
So Im kinda stuck with no idea where to turn.

UGH - this is the second time I've continued to plug away at something after I asked, only to hit upon a solution. apperantly the version Im am using is newer than the examples and ExtractJwt.fromHeader() should be .fromAuthHeaderWithScheme("jwt"). It is frustrating that it did not error, and did not progress enough to log, however - NOW I get my console log, and can see my payload... I hope this helps someone else. (I am frustrated with the pace and changes made to js libs, that destroy backwards compatibility, and do not clearly document a path, I understand kinda why it happens, but it makes learning and troubleshooting very frustrating)

Related

How to decode token in Vue.js?

I got a token after I successfully logged in. I need to be able to parse + decode/descrypt it to see the permission information inside that. How would I do that?
I tried
// token is accessible
var decoded = jwt_decode(token)
console.log('decoded', decoded)
I kept getting
Here is my token
"e2kEd...LIPH0="
I'm using Vue.js v2.
"InvalidTokenError"
How do I know if my token is compatible with jwt_decode() ?
Try #2
Paste my token here :
https://jwt.io/
Try #3
If I base64_decode() it, I see this
{iversI�iuser{inameSibheng#test.comiapplSiVCiserv[$U#i0-�8rDaiperm[{inameSiEIDiparm[{inameSiAPPidataSiVC}]idataSi COLM,DFQL}{inameSiEIDiparm[{inameSiAPPidataSi*}]idataSiECNVF,CNVZ,DFQL,DJ1L,FV8Z,HY0B,N94X,RD8L,W3XV,X3CY,XPH4,YX4N,ZR10,COLM}{inameSi
VC_GET_EIDiparm[{inameSiBRANDidataSiBROO}]idataT}]}irelm[$U#i'$}s,9ialgoSi
SHA256-RSAisign[$U#I�ZϏpRV,lYt
>Ni_h{,*wE&!?`h±VmSr,n>쏝?L+7_d]JIVl1s:Gɳ<}`
The core piece of info that I really really need is BROO
It's there, but I can't seem to parse it.
This decoded works for nuxt js and vue js. Just install vue-jwt-decode and follow this code. Good luck
Node js Login Controller
static async loginUser(req, res){
req.body.password = await hashPassword(req.body.password);
const user = req.body;
await UserServiceClass.loginUser(user).
then((respond)=>{
const user = {id:respond._id,username:respond.username};
const access_token = generateToken(user);
const refresh_token = refreshToken(user);
res.status(200).json({access_token:access_token, refresh_token:refresh_token});
}).
catch((err)=>{
res.status(500).json({login_error:err})
})
}
Vue js Login Page
<script setup>
import VueJwtDecode from 'vue-jwt-decode';
let current_user = reactive({})
const login = async () => {
console.log(user);
await useFetch('http://localhost:4000/user/login',{
method:'POST',
body:user
}).then((respond)=>{
//Keep Token inside of window localstorage
localStorage.setItem('user', respond.data.value.access_token);
}).catch((err)=>{
console.log('err : ', err);
})
}
const decode = () => {
//Take token from window local storage
let token = localStorage.getItem('user');
try{
let decoded = VueJwtDecode.decode(token)
current_user = decoded;
}
catch(err){
console.log('token is null: ',err);
}
}
</script>

req.isAuthenticated() returns FALSE (express-session, passport-local)

Edit: I got the cookie to be set by transferring app.use(session({...})) from register.js to app.js before I declare use of the router in app.js. However, the problem - req.isAuthenticated() returning false, still persists.
I'm trying to build a sign up flow using passport-local, express-session and mongodb for my backend.
When I register a new user, it seems to work fine and the user gets created in my database as desired. I can also access req.user in my passport.authenticate() callback post registration. However, when I redirect to a new route using res.redirect(), req.isAuthenticated() returns false on my new route.
Upon checking the cookies in my browser, it seems that express-session never saves the session as it is supposed to. There is no cookie from my localhost. I've done hours of research, and most answers I've come across just relate to double-checking the sequence of code when initializing. I've done this countless times, as well as tried to use both passport.serializeUser(User.serializeUser()); and passport.serializeUser(function(user, done) { done(null, user.id); }); to make sure I'm doing that step correctly. I can't seem to figure out why I'm having this issue. Any and all help will be deeply appreciated! Relevant snippets from my code -
Register.js (Router)
var express = require('express');
const session = require('express-session');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const passportLocalMongoose = require('passport-local-mongoose');
var router = express.Router();
const app = express();
app.use(bodyParser.urlencoded({extended: true}));
app.use(session({
secret:"Edit Later.",
resave:true,
saveUninitialized:true
}));
app.use(passport.initialize());
app.use(passport.session());
const userSchema = new mongoose.Schema({
name:String,
username:String,
contactNumber:String
});
userSchema.plugin(passportLocalMongoose);
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
router.post('/', function(req, res, next) {
const reCaptchaKey = "<MYKEY>";
var userCaptchaToken = req.body['g-recaptcha-response'];
axios.post('https://www.google.com/recaptcha/api/siteverify', null, {params: {
secret: reCaptchaKey,
response: userCaptchaToken
}}).then(response => {
if (response.data.success === true) {
User.register({username: req.body.username, name: req.body.fullName}, req.body.password,
function(err, user) {
if (err) {
console.log(err);
// res.redirect('/views/register.html');
} else {
passport.authenticate('local', {session:true})(req, res, function() {
console.log(req.user);
console.log(req.session);
res.redirect('/profile');
console.log("Done!");
});
}
});
} else if (response.data.success === false) {
console.log("Captcha failed.");
}
}).catch(error => {
console.log(error);
});
});
module.exports = router;
Profile.js (Router)
const express = require('express');
const router = express.Router();
router.get('/', function(req, res) {
if (req.isAuthenticated()) {
res.render('profile')
} else {
res.redirect('/register')
console.log('Not a user.')
}
})
module.exports = router;
App.js
var registrationRouter = require('./routes/register');
var profileRouter = require('./routes/profile');
app.use('/register', registrationRouter);
app.use('/profile', profileRouter);
module.exports = app;
So after hours of trying, I figured it out. My issue was I used the following code in Register.js
app.use(session({
secret:"Edit Later.",
resave:true,
saveUninitialized:true
}));
app.use(passport.initialize());
app.use(passport.session());
This was a problem because Register.js was being used as a router, and I directed all requests to this route via App.js. This led to the app not being configured properly before the requests were handled by Register.js. The above lines are configuration code and MUST be written before app.use('/register', registrationRouter); in App.js. Thus, the fix was simply to move these lines over to App.js like so -
\\configure App
app.use(session({
secret:"Edit Later.",
resave:true,
saveUninitialized:true
}));
app.use(passport.initialize());
app.use(passport.session());
\\handle router
app.use('/register', registrationRouter);

JSforce not integrating with express in Node

To give some context, I am a front end dev tasked with intergrating salesforce into a react app. This is a new learning curve for me as I am a SF newbie. I have been looking for a way to make intergration easier and I came across a video that showed how I can use a node packaged called JSforce to auth and fetch data from SF to my node express backend. I did as the video suggested but something appears to be not working as I am not console logging anything. Can anyone who has experience in using Jsforce take a look at my code below and let me know where I have gone wrong?
const express = require('express');
const app = express();
const port = 5000;
const jsforce = require('jsforce');
const username = 'blah';
const password = 'blah+ security token';
var conn = new jsforce.Connection({
// you can change loginUrl to connect to sandbox or prerelease env.
loginUrl: 'https://tahina-test2-dev-ed.my.salesforce.com/'
});
conn.login(username, password, function(err, userInfo) {
if (err) {
return console.error(err);
}
// Now you can get the access token and instance URL information.
// Save them to establish connection next time.
console.log(conn.accessToken);
console.log(conn.instanceUrl);
// logged in user property
console.log('User ID: ' + userInfo.id);
console.log('Org ID: ' + userInfo.organizationId);
// ...
conn.sobject('Account').retrieve('0012X000022HhE5QAK', function(err, account) {
if (err) {
return console.error(err);
}
console.log('Name : ' + account.Name);
// ...
});
});
app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`));

Here-API 401 : "Invalid app_id app_code combination"

I am using an Angular front-end with a Nodejs backend. Im currently proxying all my front-end requests through my express server. However when I make my http request to the Here API I am rejected due to an invalid combination of app_id and app_code.
angular service
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http'
import { HttpParams } from '#angular/common/http'
#Injectable({
providedIn: 'root'
})
export class GetReqPlaces {
constructor(private http: HttpClient) { }
getPlaces(wLong,sLat,eLong,nLat){
// let obj = {params: {westLong: wLong, southLat: sLat, eastLong:eLong, northLat:nLat }};
let params = new HttpParams().set("westLong" , '-97.783').set("southLat", '30.231').set( "eastLong" , '-97.740').set("northLat", '30.329');
return this.http.get( 'api/find/places', { params : params}).subscribe(res=>console.log(res))
}
}
server.js
const express = require("express")
const bodyParser = require("body-parser")
const cors = require("cors")
const path = require("path")
const app = express();
const request = require("request")
const environment= require('./keys')
app.use(cors());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
let reqPath = __dirname.substring(0,__dirname.length-7)
app.use(express.static(path.join(reqPath, '/dist/angular-places-search')));
app.get('/api/find/places', (req, res) => {
let appId = environment.environment.appId;
let appCode = environment.environment.appCode;
let URL= `https://places.cit.api.here.com/places/v1/discover/search?app_id={${appId}}&app_code={${appCode}}&in=${req.query.westLong},${req.query.southLat},${req.query.eastLong},${req.query.northLat}&pretty`;
console.log(URL)
request(URL, function (error, response, body) {
let data={
body:body,
};
console.log(error,response)
res.send(data);
});
});
app.get('/test', (req, res) => res.send('Well this route was a hit! Bada....tsss'));
// CATCH ALL
app.get('*', (req, res) => {
res.sendFile(path.join(reqPath, 'dist/angular-places-search/index.html'));
});
app.listen(4000, () => console.log(`Express server running on port 4000`));
Before this I was running into CORS and request issues but I think I sorted those out. Based on my research on this same error code (In the context of the framework that Im working in), people overwhelmingly suggest to wait for tokens to register with Here API. Waiting two days is enough I think, still doesnt work. Then there is the very popular solution of just scratching the Here freemium and starting a new project, which I did, and which did not solve my issue. Very few things I have 100% certainty on but I did copy my keys correctly and the URL path built is according to the required Here syntax.
If anyone has any insight you will be my Hero, and also the catalyst for my continued learning :D. Happy Sunday!
In addition the incoming message I get through express is :
method: 'GET',
path: '/places/v1/discover/search?app_id=%notmyid%7D&app_code=%normycode%7D&in=-97.783,30.231,-97.740,30.329&pretty'
However i dont know why it is setting the app_id=% instead of using {}, when i console log the URL it is correct, with my app_id and app_code
The %7D is the url encoded value of the symbol } (urlencoding) which is done by most libraries. For using the HERE API you should not enclose the app_id/app_code between {}. They should be provided directly as strings, check the examples

npm restful api suddenly no longer working

I followed this tutorial to create a restful api with npm and postgres
Designing a RESTful API With Node and Postgres
I got everything to work without a problem, closed the server and went to other things.. when I got back, the routing stopped working suddenly giving 404 error.. I checked everything related to routing and I can't find the problem!
When I connect to localhost:3000 I get the correct express homepage
but when I try to access the api, localhost:3000/api/patients the 404 error page appears
Here is my code
index.js
var express = require('express');
var router = express.Router();
var db = require('../queries');
router.get('/api/patients', db.getAllPatients);
module.exports = router;
queries.js
var promise = require('bluebird');
var options = {
// Initialization Options
promiseLib: promise
};
var pgp = require('pg-promise')(options);
var connectionString = 'postgres://localhost:5432/maindb'
var db = pgp(connectionString);
module.exports = {
getAllPatients: getAllPatients
}
function getAllPatients(req, res, next) {
db.any('select * from patients where deleted = false')
.then(function (data) {
res.status(200)
.json({
status: 'success',
data: data,
message: 'Retrieved ALL patients'
});
})
.catch(function (err) {
return next(err);
});
}
It seems something was wrong with express installation, something corrupted it.
I recreated the project from point zero and specified which version of express and bluebird to install, and everything seems to work fine without any problems.