how can i fix my express backend redirect to backend port instead of redirect to frontend port - express

on my front end(vue on port 9999),the axios request is:
this.$axios.post('/login', {
username: this.username,
password: this.password
}).then((response) => {
if (response) {
if (response.data.code === 200) {
this.$store.commit('login',response.data.result);
this.$router.push({path: '/'})
and in my backend(express on port 7890) route is:
app.post('/login',
passport.authenticate('local', {
successRedirect: '/loginSuccess',
failureRedirect: '/loginError',
failureFlash: true
})
);
app.get('/loginSuccess', function (req, res) {
console.log(req.baseUrl);
res.send(responseToJson(200, req.user, 'login successed!'));
});
app.get('/loginError', function (req, res) {
res.send(responseToJson(500, null, 'ユーザーまたはパスワードが正しくありません.....'));
});
but when i login,it's show:
GET http://localhost:9999/loginSuccess 404 (Not Found)
dispatchXhrRequest # xhr.js?b50d:187
xhrAdapter # xhr.js?b50d:13
dispatchRequest # dispatchRequest.js?5270:53
request # Axios.js?0a06:108
Axios.<computed> # Axios.js?0a06:140
wrap # bind.js?1d2b:9
login # Login.vue?7463:46
invokeWithErrorHandling # vue.runtime.esm.js?2b0e:1863
invoker # vue.runtime.esm.js?2b0e:2188
original._wrapper # vue.runtime.esm.js?2b0e:6961
Login.vue?7463:63 Error: Request failed with status code 404
at createError (createError.js?2d83:16:1)
at settle (settle.js?467f:17:1)
at XMLHttpRequest.onloadend (xhr.js?b50d:54:1)
my proxy config is :
devServer: {
port:9999,
proxy: {
'/api': {
target: 'http://localhost:7890/',
changeOrigin: true,
pathRewrite: {
'^/api': '/'
}
}
}
},
it's backend request is redirect to frontend's port.
how can i change backend's redirect to backend port?

Try the below option as mentioned in the passportjs link
app.post('/login',
passport.authenticate('local', {
failureRedirect: '/loginError',
failureFlash: true
}, (req, res) => {
res.status(200).send({user: req.user});
})
);

Related

Nextjs API folder call - 500 error in production

I have an api folder in my next.js app for some server side endpoints:
import { NextApiRequest, NextApiResponse } from 'next'
import Cors from 'cors'
// Initializing the cors middleware
const cors = Cors({
methods: ['GET', 'HEAD', 'POST'],
origin: '*',
optionsSuccessStatus: 200,
})
// Helper method to wait for a middleware to execute before continuing
// And to throw an error when an error happens in a middleware
function runMiddleware(req, res, fn) {
return new Promise((resolve, reject) => {
fn(req, res, (result) => {
if (result instanceof Error) {
return reject(result)
}
return resolve(result)
})
})
}
export default async (req, res) => {
await runMiddleware(req, res, cors)
const POSKEY = process.env.POSKEY
const PAYEE = process.env.PAYEE
const { currency, url, locale, price } = req.body
const currentUrl = url
const apiResult = await fetch(
'https://api.test.barion.com/v2/Payment/Start',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': 3495,
},
body: JSON.stringify({
PosKey: POSKEY,
PaymentType: 'Immediate',
GuestCheckout: true,
FundingSources: ['All'],
Currency: currency,
RedirectUrl: currentUrl,
CallbackUrl: currentUrl,
Locale: locale,
Transactions: [
{
Payee: PAYEE,
Total: price,
Items: [
{
Name: 'Teszt',
Description: 'Test item comment',
Quantity: 1,
Unit: 'pc',
UnitPrice: 1,
ItemTotal: 1,
SKU: 'SM-01',
},
],
},
],
}),
}
)
.then((result) => {
return result.json()
})
.catch((error) => {
console.error(error)
})
res.status(200).json({ url: apiResult.GatewayUrl })
}
When I call the endpoint, in development it works perfectly:
But in production I got 500 error. (deployed to vercel)
Error in the console on vercel:
[POST] /apigateway/ 23:30:28:53
2022-06-27T21:30:28.595Z e8c57750-4647-4e7a-b62e-6221abc141ac ERROR Error: Cannot find module '/var/task/node_modules/next/dist/server/next.js'.
Please verify that the package.json has a valid "main" entry
at tryPackage (internal/modules/cjs/loader.js:321:19)
at Function.Module._findPath (internal/modules/cjs/loader.js:534:18)
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:888:27)
at Function.Module._load (internal/modules/cjs/loader.js:746:27)
at Module.require (internal/modules/cjs/loader.js:974:19)
at require (internal/modules/cjs/helpers.js:101:18)
at Object.5199 (/var/task/.next/server/pages/api/gateway.js:20:39)
at webpack_require (/var/task/.next/server/webpack-api-runtime.js:25:42)
at webpack_exec (/var/task/.next/server/pages/api/gateway.js:109:39)
at /var/task/.next/server/pages/api/gateway.js:110:28 { code: 'MODULE_NOT_FOUND', path:
'/var/task/node_modules/next/package.json', requestPath: 'next' }
RequestId: e8c57750-4647-4e7a-b62e-6221abc141ac Error: Runtime exited
with error: exit status 1 Runtime.ExitError
What other configuration should I add to my next.config file to make it work, I am beginner with this api.
UPDATE:
This solved my problem... https://github.com/vercel/next.js/issues/34844
The problem was with the .js file wrong import:
Same issue here: https://github.com/vercel/next.js/issues/34844#issuecomment-1055628706
TLDR:
Remove the import { NextApiRequest, NextApiResponse } from "next";

setting cookie after google passport callback

I am using facebook and google oauth2 login using passport js, with this flow
User clicked the login button
Redirects to facebook/google auth page (depending on what login the user chooses)
The auth page redirects back to a callback page (/auth/callback/[provider])
A passport express middleware will catch it to parse some data and then send it to a remote api of myown to sign the user in
The auth remote api will send a response back consisting the user token
A custom express middleware will catch the response to set cookie on the server
the express chain ends by route it to /profile (cookie with token is set on the browser)
/profile will then checks if there is a token, if there is not: it will redirect to /
Doing this flow on facebook login is fine, the user is successfully redirected to /profile, with all of its data and token, the google oauth2 login however seems to be doing the redirect to /profile then setting the token (step #7 then #6), so everytime the user is using google oauth2 login, its always gonna be redirected back to / since by the time it arrives at /profile, it doesnt have the token
here's the code on the above's flow
#./server.js
const express = require('express')
const next = require('next')
const Passport = require('./server/middleware/passport')
const Api = require('./server/api')
const port = parseInt(process.env.PORT, 10)
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app
.prepare()
.then(() => {
const server = express()
// ... other unrelated things
server.use(Passport.initialize())
Api.passport.facebook(server)
Api.passport.facebookCallback(server)
Api.passport.google(server)
Api.passport.googleCallback(server)
// ... other unrelated things
server.all('*', (req, res) => handle(req, res))
server.listen(port, (error) => {
if (error) throw error
// ... other unrelated things
})
})
#./server/api.js
const Passport = require('middleware/passport')
function setCookie(req, res, next) {
res.cookie('token', req.user.auth.token, {
httpOnly: true,
sameSite: 'strict',
path: '/',
secure: process.env.NODE_ENV !== 'development',
})
next()
}
function facebook(app) {
return app.get('/auth/facebook', (req, res, next) => {
Passport.authenticate('facebook', {
scope: ['email', 'public_profile']
})(req, res, next)
})
}
function facebookCallback(app) {
return app.get(
'/auth/callback/facebook',
Passport.authenticate('facebook', { session: false, failureRedirect: '/' }),
setCookie,
(req, res) => {
res.redirect('/profile')
},
)
}
function google(app) {
return app.get('/auth/google', (req, res, next) => {
Passport.authenticate('google', {
scope: [
'https://www.googleapis.com/auth/userinfo.email ',
'https://www.googleapis.com/auth/userinfo.profile ',
],
prompt: 'consent',
authType: 'rerequest',
accessType: 'offline',
})(req, res, next)
})
}
function googleCallback(app) {
return app.get(
'/auth/callback/google',
Passport.authenticate('google', { failureRedirect: '/', session: false }),
setCookie,
(req, res) => {
res.redirect('/profile')
},
)
}
module.exports = {
passport: {
facebook,
facebookCallback,
google,
googleCallback,
}
}
#./server/middleware/passport.js
const axios = require('axios')
const passport = require('passport')
const GoogleStrategy = require('passport-google-oauth20').Strategy
const FacebookStrategy = require('passport-facebook').Strategy
passport.serializeUser((user, done) => {
done(null, user)
})
passport.deserializeUser((obj, done) => {
done(null, obj)
})
function verifyCallback(req, ... , done) {
process.nextTick(async () => {
try {
const options = {
baseURL: baseUrl, // My remote api url
method: 'POST',
url: '/auth/signin',
headers: {
'Content-Type': 'application/json',
},
data: JSON.stringify({
// email, fullname, etc
}),
}
const response = await axios(options)
return done(null, response.data)
} catch (error) {
const { response } = error
return done(JSON.stringify(response.data, null, 2), null)
}
})
}
passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: callbackURLGoogle,
passReqToCallback: true,
}, verifyCallback))
passport.use(new FacebookStrategy({
clientID: process.env.FACEBOOK_CLIENT_ID,
clientSecret: process.env.FACEBOOK_CLIENT_SECRET,
callbackURL: callbackURLFacebook,
enableProof: true,
profileFields: ['id', 'name', 'email', 'picture.type(large)'],
passReqToCallback: true,
}, verifyCallback))
module.exports = passport
I console.log() things, just to figure out if it falls to the correct sequence of flow, the console doesn't seem to log anything suspicious, is there's something i am missing here?
PS: i am also using next js with custom server
I was facing the same problem and was able to send cookies by using custom callback.
router.get('/google/callback', (req, res) => {
passport.authenticate('google', {session: false, failureRedirect:'/auth/google/failure'},
async(err, user) => {
// You can send cookies and data in response here.
})(req, res)
})
Please refer custom callback section in documentation for explanation.

POST request freezes after add body-parser

I'm build vue app, and for mine app need api request to server from client, also necessary proxy any request.
It's mine vue.config.js
const producer = require('./src/kafka/producer');
const bodyParser = require('body-parser')
module.exports = {
devServer: {
setup: function (app, server) {
app.use(bodyParser.json())
app.post('/send-message', function (req, res) {
producer.send(req.body)
.then(() => {
res.json({result: true, error: null});
})
.catch((e) => {
res.status(500).json({result: false, error: e});
})
});
},
proxy: {
'/v2/order/by-number': {
target: 'http://address-here'
}
}
}
};
As you can see so i'm use body-parser app.use(bodyParser.json())
After I added it, proxying stopped working for me. Request to /send-message freezes after show me error
Proxy error: Could not proxy request path-here from localhost:8080
to http://address-here
Internet searches have not led to a solution.
For a long time, i find a solution:
Add second param jsonParser to app.post()
See full example
const producer = require('./src/kafka/producer');
const bodyParser = require('body-parser')
const jsonParser = bodyParser.json({limit: '1mb'});
module.exports = {
devServer: {
setup: function (app, server) {
app.post('/send-message', jsonParser, function (req, res) {
producer.send(req.body)
.then(() => {
res.json({result: true, error: null});
})
.catch((e) => {
res.status(500).json({result: false, error: e});
})
});
},
proxy: {
'path': {
target: 'http://address-here'
}
}
}
};

express-session not saving data

I have a simple MEAN app and I want to implement a simple "home-made" user authentication. My idea is to save the userId in the session when he logs in, and to check if userId exists in the session on each page request (for example, when getting the list of all users).
Backend - server.js:
const express = require("express");
const session = require("express-session");
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
var MemoryStore = session.MemoryStore;
app.use(
session({
name: "app.sid",
secret: "my_s3cr3t",
resave: true,
store: new MemoryStore(),
saveUninitialized: true
})
);
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cors());
const dbConfig = require("./config/database.config.js");
const mongoose = require("mongoose");
mongoose.Promise = global.Promise;
mongoose
.connect(dbConfig.url)
.then(() => {
// ...
})
.catch(err => {
// ...
process.exit();
});
require("./app/routes/user.routes.js")(app);
require("./app/routes/task.routes.js")(app);
require("./app/routes/login.routes.js")(app);
app.listen(3333, () => {
console.log("Server is listening on port 3333");
});
When a user clicks the Login button, a method from the frontend controller is called:
Frontend - login.controller.js:
vm.login = function() {
userService.getUserByUsername(vm.username).then(user => {
if (user.password === vm.password) {
console.log("Login ok");
loginService.login(user).then(($window.location.href = "/#!main"));
} else {
console.log("Login not ok");
}
});
};
Backend - login.controller.js:
exports.login = (req, res) => {
req.session.userId = req.body._id;
req.session.save(function(err) {
console.log(err); // prints out "undefined", so there's no error
});
console.log(req.session);
res.status(200).send({
message: "Login ok"
});
};
The frontend LoginController prints out "Login ok" (assuming that I entered correct credentials) and redirects me to the "main" page which uses main.controller.js:
In the meantime, the backend login controller prints out the following:
Session {
cookie:
{ path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true },
userId: '5b4746cafe30b423181ad359' }
So there is definitely a userId in the session content. However, when I get redirected to the main.html and the main.controller.js gets invoked, it calls:
loginService.getSession().then(data => console.log(data));
(I just want to check if the userId is still in the session, and later I will perform some useful actions)
The getSession() method in the frontend LoginService only does the $http call:
function getSession() {
return $http.get("http://localhost:3333/session").then(
function(response) {
return response.data;
},
function(error) {
console.log(error.status);
}
);
}
This one calls the method which is defined in the backend LoginController:
exports.getSession = (req, res) => {
console.log(req.session);
if (req.session.userId) {
res
.status(200)
.send({ message: "Session existing with userId " + req.session.userId });
} else {
res.status(404).send({ message: "Session not existing" });
}
};
The frontend call prints the status code 404 in the console, while in the backend I get the following output:
Session {
cookie:
{ path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true } }
(no userId is present...)
One more thing... In a few tutorials I saw that they are using cookie-parser. However, when I try to use it, I don't get any data from my database, only the static text is displayed. So I removed it temporarily from server.js.
EDIT:
I tried adding MongoStore to my app:
const MongoStore = require("connect-mongo")(session);
...
app.use(
session({
name: "app.sid",
secret: "G4m1F1c4T10n_#ppL1c4t10N",
resave: true,
saveUninitialized: false,
cookie: { maxAge: 600000 },
store: new MongoStore({ url: "mongodb://localhost:27017/myAppDb" })
})
);
...but nothing changed.
How can I get my sessions to work?
As I found out after talking to several people, sessions are more or less deprecated and the new way of handling these things are the tokens. So I switched to JWT and it's working great.

nuxt axios.post request with empty body

I'm trying to get nuxt with axios working.
I do the following post request (store/index.js):
login({ commit }, { username, password }) {
const data = JSON.stringify({
password
, username
})
console.log('store login ', username, password)
this.$axios.post('http://localhost:3000/api/login', data)
.then(res => {
commit('SET_USER', res.data)
})
.catch(error => {
console.log(error.response)
})
}
My backend looks like this (api/auth.js):
const express = require('express')
const session = require('express-session')
const body_parser = require('body-parser')
const app = express()
const router = express.Router()
app.use(body_parser.json())
app.use(body_parser.urlencoded({ extended: true }))
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: false
}))
router.post('/login', (req, res) => {
console.log('try to login ', req.body)
if (!req.body)
return res.status(401).json({ message: 'No body' })
if (req.body.username === 'demo' && req.body.password === 'demo') {
req.session.auth_user = { username: 'demo' }
console.log('logged in')
return res.json({ username: 'demo' })
}
res.status(401).json({ message: 'Bad credentials' })
})
My Problem is, that the req.body is always undefined. But in the error message I can see, that the params are sent. (config.data)
Does anybody has an idea what I'm missing? I use body-parser and checked everything 100 times. I guess it's something total obvious, but I can't see it.
My nuxt.config.js:
module.exports = {
...
modules: [
'#nuxtjs/axios'
, '#nuxtjs/auth'
],
router: {
middleware: ['auth']
},
serverMiddleware: ['#api/auth']
...
}
Probably you take this error also. This is caused by cors policy.
Access to XMLHttpRequest at 'http://localhost:3000/.......' from
origin 'http://127.0.0.1:3000' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
same problem occured on my project.
in server index.js change line
const host = process.env.HOST || 'localhost'
and nuxt.config.js
axios: {
baseURL: 'http://localhost:YOUR_PORT'
},
You must define bodyParser in router.
router.use(express.json())