Express-jwt is not returning any response - authentication

I'm trying to create a Login functionality using express-jwt, and using the middleware function in my app.js file. But whenever I'm trying to send a get request using the postman, it sending request for infinite of time and never returns back any error or success message.
I'm using dynamoDB as database.
here's my Login.js file
const AWS = require("aws-sdk");
const express = require("express");
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
require("dotenv").config();
AWS.config.update({ region: "us-east-2" });
const docClient = new AWS.DynamoDB.DocumentClient();
const router = express.Router();
router.post("/login", (req, res) => {
user_type = "customer";
const email = req.body.email;
docClient.get(
{
TableName: "users",
Key: {
user_type,
email,
},
},
(err, data) => {
if (err) {
res.send("Invalid username or password");
} else {
if (data && bcrypt.compareSync(req.body.password, data.Item.password)) {
const token = jwt.sign(
{
email: data.Item.email,
},
process.env.SECRET,
{ expiresIn: "1d" }
);
res.status(200).send({ user: data.Item.email, token: token });
} else {
res.status(400).send("Password is wrong");
}
}
}
);
});
module.exports = router;
Here's my jwt.js file:
const expressJwt = require("express-jwt");
require("dotenv").config();
function authJwt() {
const secret = process.env.SECRET;
return expressJwt({
secret,
algorithms: ["HS256"],
});
}
module.exports = authJwt;
And I'm trying to use the expressJwt like this in my app.js file:
app.use(authJwt); //If I'm not using this, then the code works fine without API protection
Can Anyone tell me what's wrong with my code?
Any help from your side is appreciated.

Remove function from your jwt.js ,it should look like this
const expressJwt = require('express-jwt');
const secret = process.env.secret
const authJwt = expressJwt({
secret,
algorithms:['HS256']
})
module.exports = authJwt;

Related

How to display logged in username on the screen | express session

I want take the user info like email , username and display it on dashboard.ejs . i tried req.session.username and req.body.username but never worked . please help me in this !!
i want handle profile management for the web so by retriving the username help fetch the info about the user in the database
`
const express = require("express");
const app = express();
const bcrypt = require("bcryptjs");
const session = require("express-session");
const MongoDBSession = require("connect-mongodb-session")(session);
const mongoose = require("mongoose");
const UserModel = require("./models/user");
const mongoURI = "mongodb://localhost:27017/sessions";
mongoose.connect( mongoURI, {
useNewUrlParser : true,
// useCreateIndex : true,
// useUnifiedToplogy : true
}).then((res)=>{
console.log("MongoDB connected");
})
const store = new MongoDBSession({
uri : mongoURI,
collections : "mySessions"
})
const isAuth = (req,res,next)=>{
if(req.session.isAuth){
next();
}else{
res.redirect("/login");
}
}
app.use(session({
secret : "key that will sign a cookie",
resave : false,
saveUninitialized : false,
store : store
}))
app.set("view engine", "ejs");
app.use(express.urlencoded({ extended: true }));
app.get("/", (req,res)=>{
res.render("landing");
});
// Login Page
app.get("/login", (req,res)=>{
res.render("login");
} );
app.post("/login", async(req,res)=>{
const {email , password} = req.body;
const user = await UserModel.findOne({email});
if (!user){
return res.redirect("/login");
}
const isMatch =await bcrypt.compare(password , user.password);
if(!isMatch){
return res.redirect("/login");
}
req.session.isAuth = true;
res.redirect("/dashboard");
});
// Register Page
app.get("/register", (req,res)=>{
res.render("register");
});
app.post("/register", async (req,res)=>{
const {username , email , password } = req.body;
let user = await UserModel.findOne({email});
if (user){
return res.redirect("/register");
}
const hashPsw =await bcrypt.hash(password,12);
user = new UserModel({
username,
email,
password:hashPsw
});
user.save();
console.log("saved");
if (!user){
return res.redirect("/login");
}
const isMatch =await bcrypt.compare(password , user.password);
if(!isMatch){
return res.redirect("/login");
}
req.session.isAuth = true;
res.redirect("/dashboard");
});
// Dashboard Page
app.get("/dashboard", isAuth , (req,res)=>{
console.log(req.session);
res.render("dashboard");
});
app.post("/logout", (req,res)=>{
req.session.destroy((err)=>{
if (err) throw err;
res.redirect("/");
})
});
app.listen(3500 , ()=>{
console.log("server running on port 3500");
})
`
One of the options would be to supply that in the POST request's response. For example, Author has inserted it in a pug view here like h2 Username: #{user.name} and has supplied it as variable while page rendering in response here with res.render('profile', {title: "My Profile", user: req.cookies.userData});.
Since you have used ejs instead of pug, the injecting I did with #{} can be done with <%= YOUR_VARIABLE %> . Please, see this for a tutorial and ejs docs for more examples.

Stripe Error: No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe?

So first what i want to say, is that none of the public questions on stackoverflow did not helped me with this error. I am running the Stripe CLI on my local machine like this : stripe listen --forward-to localhost:4242/webhook , but weirdly when i try to proccess all the events inside i get the error :
No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe? https://github.com/stripe/stripe-node#webhook-signing
I have already tried using request.rawBody , but it didn't fix my issue.
I am posting all of the code, so maybe someone will see what i can't and help me fixing it
router.js :
let express = require('express');
let router = express.Router();
let bodyParser = require('body-parser')
let postMong = require('./post')
require("dotenv").config()
router.use(express.json());
const YOUR_DOMAIN = 'http://localhost:4242';
const stripe = require('stripe')(process.env.PUBLIC_KEY);
router.post('/checkout/create-order', async (req, res) => {
const price = req.body.order.stripe_price || undefined,
product = req.body.order.stripe_product || undefined
const session = await stripe.checkout.sessions.create({
shipping_address_collection: {
allowed_countries: ['US', 'CA'],
},
shipping_options: [
{
shipping_rate_data: {
type: 'fixed_amount',
fixed_amount: {
amount: 2499,
currency: 'usd',
},
display_name: 'International Shipping',
// Delivers between 5-7 business days
delivery_estimate: {
minimum: {
unit: 'week',
value: 2,
},
}
}
},
],
line_items: [
{
price: price,
quantity: 1,
},
],
payment_method_types: ["card", 'us_bank_account'],
mode: 'payment',
success_url: `${YOUR_DOMAIN}/success.html`,
cancel_url: `${YOUR_DOMAIN}/index.html`,
});
res.json({url: session.url})
});
router.post('/posts/add', async (req,res)=>{
try{
const {author, id, name, picture, pixels, price, size, stripe_price, stripe_product} = req.body
const pos = await postMong.create( {author, id, name, picture, pixels, price, size, stripe_price, stripe_product})
res.json(pos)
} catch(e){
res.status(500).json(e)
}
})
router.get('/ideas', async (req,res)=>{
try{
const posts = await postMong.find()
return res.json(posts);
} catch(e){
reject(res.status(500).json(e))
}
})
const endpointSecret = 'whsec_****';
const fulfillOrder = (session) => {
// TODO: fill me in
console.log("Fulfilling order", session);
}
router.use(bodyParser.json());
router.post('/webhook', (request, response) => {
const payload = request.body;
const sig = request.headers['stripe-signature'];
let event;
try {
event = stripe.webhooks.constructEvent(request.rawBody, sig, endpointSecret);
console.log(event)
} catch (err) {
console.log(err.message)
return response.status(400).send(`Webhook Error: ${err.message}`);
}
// Handle the checkout.session.completed event
if (event.type === 'checkout.session.completed') {
const session = event.data.object;
// Fulfill the purchase...
fulfillOrder(session);
}
response.status(200);
});
module.exports = router
server.js :
const router = require("./router");
const account = require("./routerAccount");
const express = require('express');
const mongoose = require("mongoose")
const app = express();
const cors = require('cors')
var session = require('express-session');
require("dotenv").config()
const db_url = process.env.MONGO_URL
app.use(session({
cookie: {
httpOnly: true
},
rolling: true,
resave: true,
saveUninitialized: true,
secret: '~~~~~'
}));
app.set('view engine','ejs');
app.use(express.static('public'));
//app.use(express.json());
app.use(cors())
app.use('/', router)
app.use('/', account)
async function startApp(){
try{
await mongoose.connect(db_url, {
useUnifiedTopology: true,
useNewUrlParser:true
})
app.listen(4242, () => {console.log("server is working")})
} catch(e) {
console.log("some error appearead" + e)
}
}
startApp()
Normally when you see this error, it means that, either the HTTP request body Stripe sent to your webhook handler has been altered in some way or You may not be using the correct webhook secret.
The most likely reason it is throwing an exception is because your router is parsing body as JSON with router.use(express.json()). constructEvent requires the raw, unparsed body you receive from the request to verify the signature. To verify you have the raw body you can print it out and see if you get something like <Buffer 28 72 10..>
You can tell your router to keep the request body raw by setting something like this on your route router.use('/webhook', express.raw({type: "*/*"}))
I found the solution for my problem.
What i added is
app.use( "/webhook",express.raw({ type: "*/*" }))
in my server.js file.

how to delete cookie without reloading the page using custom express server in next js

this is my routes file
const User = require("./schema");
const jwt = require("jsonwebtoken");
const bcrypt = require("bcrypt");
const express = require("express");
const server2 = express();
const routes = (server,app) => {
// this route is for signup
server.post("/api/signup", async (req,res) => {
const { fullName, emailId, password }=req.body;
const signupData = new User({
fullName,
emailId,
password: await bcrypt.hash(password,10),
});
const token = await signupData.generateToken();
console.log(`token: ${token}`);
if (token != undefined) {
res.cookie("token",token,{
httpOnly: true,
secure: true,
sameSite: "strict",
path: "/",
maxAge: 1000*60*2
})
res.send({message:"signedup successfuly"});
res.end();
}
const saveUser = await signupData.save();
});
// this route is for user varification
server.get("/api", async (req,res) => {
const token = req.cookies.token;
console.log(`token: ${token}`);
if (token != undefined) {
const _id = jwt.verify(token,process.env.JWT_SECRET)._id;
const findUser = await User.findOne({ _id });
res.send(findUser);
} else {
res.send({fullName:""});
}
});
// this route is for logout
server.get("/api/logout",async (req, res) => {
try {
const token = req.cookies.token;
const _id = jwt.verify(token, process.env.JWT_SECRET)._id;
await User.updateOne({ _id }, { $pull: { tokens: { token }}});
res.clearCookie("token");
console.log(req.cookies.token)
res.send({message:""})
res.end();
} catch(err) {
console.log(err)
}
});
}
module.exports = routes;
When I do signup cookie is setting without reloading the page its working but that's not a problem the problem is when I do logout its not deleting cookie without reloading the page when I reload the page its working but without reloading the page its not working I am using custom express server in nextjs

Why is my Express res not being returned to Vue.js component?

I'm trying to make an axios HTTP request call to an express route to retrieve a response from passport spotify. I am struggling on sending the response from express to my vue.js component. I am using Nuxt.js.
spotify.vue
export default {
data: function() {
return {
userInfo: null
};
},
mounted() {
this.$axios.get("/auth/spotify")
.then((response) => {
userInfo = response;
});
}
};
server/index.js
const express = require('express');
const passport = require('passport');
const SpotifyStrategy = require('passport-spotify').Strategy;
const keys = require('../config/keys');
const app = express();
async function start () {
passport.use(
new SpotifyStrategy(
{
clientID: keys.spotifyClientID,
clientSecret: keys.spotifyClientSecret,
callbackURL: '/auth/spotify/callback'
},
function(accessToken, refreshToken, expires_in, profile, done) {
console.log(profile);
}
)
);
app.get('/auth/spotify', passport.authenticate('spotify'), function(req,res) {
res.json(data);
});
app.get('/auth/spotify/callback', passport.authenticate('spotify'));
}
When accessing localhost:3000/auth/spotify the data I am looking for is logged. I am wondering why res.json() or res.send() is not passing the data to the axios promise in my component.
Any help would be appreciated, Thanks in advance!!!

Request origin cannot be verified - Shopify

I'm developing an app for Shopify. Currently under development stage. Until now, I have successfully managed to authorise the app and then redirect it back to admin page using the Embedded App SDK. However, when I return to the admin page, it gives me an error saying Request origin cannot be verified.
The console shows Failed to load resource: the server responded with a status of 403 (Forbidden)
The URL in the console is something like this https://myshop.myshopify.com/admin/apps/dfdjf4343343434343434bfdf/shopify/shopify/callback?code=ffdfdffd&hmac=fdfdfdfdfdfdfdfdfddfdfdfdfdf&shop=myshop.myshopify.com&state=151193864548800&timestamp=1511938648
The fdfdfdfdfdfdfdfdfddfdfdfdfdf are just random characters that I've replaced instead of a hash. FYI - I've removed the app name and user profile name and avatar from the image.
This is happening because, you are unable to match state, that is set in cookie, while responding with redirect url
const ShopifyToken = require('shopify-token')
const forwardingAddress = process.env.HOST
const shopifyToken = new ShopifyToken({
sharedSecret: process.env.SHOPIFY_API_SECRET,
redirectUri: forwardingAddress + '/shopify/callback',
apiKey: process.env.SHOPIFY_API_KEY
})
const shopify = {
// use this for authentication
auth: (req, res, next) => {
const shop = req.query.shop
if (!shop) {
return res.status(400).send('Missing shop parameter. Please add ?shop=your-development-shop.myshopify.com to your request')
}
const shopRegex = /^([\w-]+)\.myshopify\.com/i
const shopName = shopRegex.exec(shop)[1]
const state = shopifyToken.generateNonce()
const url = shopifyToken.generateAuthUrl(shopName, scopes, state)
res.cookie('state', state)
res.redirect(url)
},
// use this as your callback function
authCallback: async (req, res) => {
const { shop, hmac, code, state } = req.query
const stateCookie = cookie.parse(req.headers.cookie).state
if (state !== stateCookie) {
// you are unable to set proper state ("nonce") in this case, thus you are getting this error
return res.status(403).send('Request origin cannot be verified')
}
if (!shop || !hmac || !code) {
res.status(400).send('Required parameters missing')
}
let hmacVerified = shopifyToken.verifyHmac(req.query)
console.log(`verifying -> ${hmacVerified}`)
// DONE: Validate request is from Shopify
if (!hmacVerified) {
return res.status(400).send('HMAC validation failed')
}
const accessToken = await shopifyToken.getAccessToken(shop, code)
const shopRequestUrl = 'https://' + shop + '/admin/shop.json'
const shopRequestHeaders = {
'X-Shopify-Access-Token': accessToken
}
try {
const shopResponse = await request.get(shopRequestUrl, { headers: shopRequestHeaders })
res.status(200).end(shopResponse)
} catch (error) {
res.status(error.statusCode).send(error.error.error_description)
}
}
}
Simple as this is, also make sure that the protocol matches from what you typed in to start the app install.
If you accidentally use http for http://you.ngrok.io/ but your callback redirects to https (i.e. https://you.ngrok.io/auth/callback), the OAuth handshake will fail.
const express = require('express');
const router = express.Router();
const dotenv = require('dotenv').config();
const cookie = require('cookie');
const requestPromise = require('request-promise');
const ShopifyToken = require('shopify-token');
const scopes = "write_products";
const forwardingAddress = process.env.HOST;
var shopifyToken = new ShopifyToken({
sharedSecret: process.env.SHOPIFY_API_SECRET,
redirectUri: forwardingAddress + '/shopify/callback',
apiKey: process.env.SHOPIFY_API_KEY
})
router.get('/shopify', (req, res) => {
const shop = req.query.shop;
if (!shop) {
return res.status(400).send('Missing shop parameter. Please add ?shop=your-development-shop.myshopify.com to your request')
}
const shopRegex = /^([\w-]+)\.myshopify\.com/i
const shopName = shopRegex.exec(shop)[1]
const state = shopifyToken.generateNonce();
const url = shopifyToken.generateAuthUrl(shopName, scopes, state);
res.cookie('state', state);
res.redirect(url);
});
router.get('/shopify/callback', (req, res) => {
const { shop, hmac, code, state } = req.query;
const stateCookie = cookie.parse(req.headers.cookie).state;
if (state !== stateCookie) {
// you are unable to set proper state ("nonce") in this case, thus you are getting this error
return res.status(403).send('Request origin cannot be verified')
}
if (!shop || !hmac || !code) {
res.status(400).send('Required parameters missing')
}
let hmacVerified = shopifyToken.verifyHmac(req.query)
console.log(`verifying -> ${hmacVerified}`)
// DONE: Validate request is from Shopify
if (!hmacVerified) {
return res.status(400).send('HMAC validation failed')
}
const accessToken = shopifyToken.getAccessToken(shop, code);
const shopRequestUrl = 'https://' + shop + '/admin/products.json'
const shopRequestHeaders = {
'X-Shopify-Access-Token': accessToken
}
try {
const shopResponse = requestPromise.get(shopRequestUrl, { headers: shopRequestHeaders })
res.status(200).send(shopResponse)
} catch (error) {
res.status(error.statusCode).send(error.error.error_description)
}
});
module.exports = router;