I'm making a website. I am in the dashboard stage and have a problem because I get the error TypeError: req.next is not a function. I want to make a dashboard subpage. I am using the isAuthorized function to check if the user is logged in.
Please help.
C:\Users\olios\Desktop\Moje rzeczy\Avi\Boty\Auth\node_modules\mysql\lib\protocol\Parser.js:437
throw err; // Rethrow non-MySQL errors
^
TypeError: req.next is not a function
at done (C:\Users\olios\Desktop\Moje rzeczy\Avi\Boty\Auth\node_modules\express\lib\response.js:1007:25)
at tryRender (C:\Users\olios\Desktop\Moje rzeczy\Avi\Boty\Auth\node_modules\express\lib\application.js:642:5)
at Function.render (C:\Users\olios\Desktop\Moje rzeczy\Avi\Boty\Auth\node_modules\express\lib\application.js:592:3)
at ServerResponse.render (C:\Users\olios\Desktop\Moje rzeczy\Avi\Boty\Auth\node_modules\express\lib\response.js:1012:7)
at C:\Users\olios\Desktop\Moje rzeczy\Avi\Boty\Auth\src\routes\dashboard.js:31:21
at Query.<anonymous> (C:\Users\olios\Desktop\Moje rzeczy\Avi\Boty\Auth\src\database\database.js:35:9)
at Query.<anonymous> (C:\Users\olios\Desktop\Moje rzeczy\Avi\Boty\Auth\node_modules\mysql\lib\Connection.js:526:10)
at Query._callback (C:\Users\olios\Desktop\Moje rzeczy\Avi\Boty\Auth\node_modules\mysql\lib\Connection.js:488:16)
at Query.Sequence.end (C:\Users\olios\Desktop\Moje rzeczy\Avi\Boty\Auth\node_modules\mysql\lib\protocol\sequences\Sequence.js:83:24)
at Query._handleFinalResultPacket (C:\Users\olios\Desktop\Moje rzeczy\Avi\Boty\Auth\node_modules\mysql\lib\protocol\sequences\Query.js:149:8)
[nodemon] app crashed - waiting for file changes before starting...
dashboard.js
const router = require('express').Router()
const database = require('./../database/database')
const fs = require('fs')
const dirAdmin = __dirname + `./../public/config/admin.yaml`
let data
data = JSON.parse(fs.readFileSync(dirAdmin))
function isAuthorized(req, res, next){
if(req.user){
next()
}else{
res.redirect('/auth')
}
}
router.get('/', isAuthorized, (req, res) => {
database.sql("SELECT * FROM servers", (rows) => {
for(const f of data){
if(f == req.user.id){
res.render('dashboard/dashboard', {
guilds: req.user.guilds,
servers: rows,
user: req.user,
admin: true
})
}else{
res.render('dashboard/dashboard', {
guilds: req.user.guilds,
servers: rows,
user: req.user,
admin: false
})
}
}
})
})
router.get('/admin', isAuthorized, (req, res) => {
database.sql("SELECT * FROM servers", (rows) => {
for(const f of data){
if(f == req.user.id){
res.render('admin/admin', {
guilds: req.user.guilds,
servers: rows,
user: req.user,
admin: true
})
}else{
res.render('admin/admin', {
guilds: req.user.guilds,
servers: rows,
user: req.user,
admin: false
})
}
}
})
})
module.exports = router
auth.js
const router = require('express').Router()
const passport = require('passport')
router.get('/', passport.authenticate('discord'))
router.get('/redirect', passport.authenticate('discord', {
failureRedirect: '/',
successRedirect: '/dashboard'
}), (req, res) => {
res.send(200)
})
router.get('/logout', (req, res) => {
if(req.user){
req.logOut()
res.redirect('/')
}else{
res.redirect('/')
}
})
module.exports = router
discordStretegy.js
const DiscordStrategy = require('passport-discord').Strategy
const passport = require('passport')
const { User } = require('./../database/database')
passport.serializeUser((user, done) => {
console.log("Serialize")
done(null, user.id)
})
passport.deserializeUser(async (id, done) => {
console.log("Deserializing")
const user = await User.findOne({
where: {
id: id
}
})
if(user){
done(null, user)
}
})
passport.use(new DiscordStrategy({
clientID: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
callbackURL: process.env.CLIENT_REDIRECT,
scope: ['identify', 'email', 'guilds'],
}, async (accessToken, refreshToken, profile, done) => {
try{
const user = await User.findOne({
where: {
id: profile.id
}
})
if(user){
console.log("User exists.")
done(null, user)
}else{
console.log("Create new user.")
const newUser = await User.create({
id: profile.id,
username: profile.username,
avatar: profile.avatar,
discriminator: profile.discriminator,
locale: profile.locale,
email: profile.email,
guilds: profile.guilds
})
done(null, newUser)
}
}catch(err){
console.log(err)
done(null)
}
}))
You can simply change your code like:
if(!req.user){
res.redirect('/auth')
}
Related
I use Vue js and node express to create a social authentification with Passport.js and i want to display a my menu if it detect a user online and use it server side.
I know my code is very bad, i try to learn steps by steps, and i seek to inform myself, so plz don't be too hard, try my best to be as possible.
That my Vue.js file default.vue :
<template>
<div>
<a-layout class="container" id="components-layout-demo-responsive">
<Menu v-if="isConnected" />
<a-layout>
<Header />
<Nuxt />
</a-layout>
</a-layout>
</div>
</template>
<script>
import axios from "axios"
export default {
data() {
isConnected: false
},
watch: {
isConnected(activeStatus) {
axios.post('/users/active-status/' {
if ( activeStatus: 1) {
console.log('User is connect, show menu')
} else {
console.log('User is disconnect, hide menu')
}
}
},
};
</script>
That my backend-express index.js :
const express = require("express");
const passport = require("passport");
const GoogleStrategy = require("passport-google-oauth20").Strategy;
const app = express()
const port = 5000
passport.use(
new GoogleStrategy({
clientID: "process.env.clientID",
clientSecret: "process.env.clientSecret",
callbackURL: '/auth/google/callback',
},
async (accessToken, refreshToken, profile, done) => {
const existingUser = await User.findOne({
providerId: profile.id,
})
if (existingUser) {
return done(null, existingUser);
}
const user = await new User({
provider: profile.provider,
providerId: profile.id,
displayName: profile.displayName,
}).save()
done(null, user);
})
)
export default {
ensureAuth: function checkAuth (req, res, next) {
if (req.isAuthenticated()) {
res.status(200).send()
return next()
} else {
res.status(404).send()
res.redirect('/')
}
},
passport.serializeUser(function (user, done) {
done(null, user.id);
});
passport.deserializeUser(function (obj, done) {
done(null, done);
});
app.post('/users/active-status/', (req, res, next) => {
const userId= req.params.id;
const status = req.params.activeStatus
console.log(userId)
res.send(status)
next();
});
I'm trying to update the data in my req.user when I change the user data like changing the email validation from false to true. What is the best way to do this? at the moment I run req.logIn again but this doesn't seem like a great solution.
So is there a way to update the user data in my req.user without running req.logIn again.
My Passport.js config:
//=============================================================================
// OAuth2.0 Setup Start
//=============================================================================
const passport = require('passport')
const bcrypt = require('bcryptjs')
const GoogleStrategy = require('passport-google-oauth20').Strategy
const LocalStrategy = require('passport-local').Strategy
const User = require('../models/User')
const userLimit = require('../routes/utils/userLimit')
passport.serializeUser(function (user, done) {
console.log('user: ', user)
done(null, user)
})
passport.deserializeUser(function (obj, done) {
done(null, obj)
})
//=============================================================================
// OAuth2.0 Google Start
//=============================================================================
passport.use(
new GoogleStrategy(
{
clientID: `${process.env.clientID}`,
clientSecret: `${process.env.clientSecret}`,
callbackURL: `${process.env.url}/auth/google/callback`,
},
function (accessToken, refreshToken, profile, done) {
User.findOne({
$or: [{ googleId: profile.id }, { googleId: null, email: profile.emails[0].value }],
}).then((user) => {
if (user === null) {
new User({
name: `${profile.name.givenName} ${profile.name.familyName}`,
email: profile.emails[0].value,
verified: true,
password: null,
picture: profile.photos[0].value,
googleId: profile.id,
})
.save()
.then((newUser) => {
userLimit()
console.log('newUser: ', newUser)
done(null, newUser)
})
.catch((err) => done(err, null))
} else if (user.googleId === profile.id) {
done(null, user)
} else if (user.googleId === null) {
done(null, false)
}
})
}
)
)
//=============================================================================
// OAuth2.0 Local Start
//=============================================================================
passport.use(
new LocalStrategy((username, password, done) => {
User.findOne({ email: username }, (err, user) => {
if (err) throw err
if (!user) return done(null, false)
if (user.googleId !== null) return done(null, false)
bcrypt.compare(password, user.password, (err, result) => {
if (err) throw err
if (result === true) {
return done(null, user)
} else {
return done(null, false)
}
})
})
})
)
I'm having a problem with my backend. Everything worked fine on localhost but after uploading to Heroku authorization stopped working.
The problem from what it looks like is a miscommunication between two scripts passport-setup.js and auth-routes.js.
passport-setup.js retrieves user information from an external database. This data is properly received in this script, here.
const passport = require('passport')
const { Strategy } = require('passport-twitter')
const keys = require('./keys')
const User = require('../models/user-model')
passport.serializeUser((user, done) => {
done(null, user.id)
})
passport.deserializeUser((id, done) => {
User.findById(id)
.then(user => done(null, user))
.catch(e => done(new Error('Failed to deserialize an user')))
})
passport.use(
new Strategy(
{
consumerKey: keys.TWITTER_CONSUMER_KEY,
consumerSecret: keys.TWITTER_CONSUMER_SECRET,
callbackURL: '/auth/twitter/redirect',
},
async (token, tokenSecret, profile, done) => {
const currentUser = await User.findOne({
twitterId: profile._json.id_str,
})
if (!currentUser) {
const newUser = await new User({
name: profile._json.name,
screenName: profile._json.screen_name,
twitterId: profile._json.id_str,
profileImageUrl: profile._json.profile_image_url,
token: token,
tokenSecret: tokenSecret,
}).save()
if (newUser) {
done(null, newUser)
}
}
done(null, currentUser)
}
)
)
But then it can't be received in the auth-routes.js script as req.user returns undefined in this case and the data can't be passed to the frontend.
const router = require('express').Router()
const passport = require('passport')
const fs = require('fs')
const MAIN_PAGE_URL = 'https://test.netlify.app'
const CLIENT_HOME_PAGE_URL = MAIN_PAGE_URL + '/createList'
router.get('/login/success', (req, res) => {
console.log(req.user, req.cookies)
if (req.user) {
const slots = JSON.parse(fs.readFileSync('./config/config.json')).slots
console.log(slots)
res.json({
success: true,
message: 'user has succesfully authenticated',
user: req.user,
slots: slots,
cookies: req.cookies,
})
}
})
router.get('/login/failed', (req, res) => {
res.status(401).json({
success: false,
message: 'user failed to authenticate',
})
//res.redirect(MAIN_PAGE_URL)
})
router.get('/logout', (req, res) => {
req.logout()
res.redirect(MAIN_PAGE_URL)
})
router.get('/twitter', passport.authenticate('twitter'))
router.get(
'/twitter/redirect',
passport.authenticate('twitter', {
successRedirect: CLIENT_HOME_PAGE_URL,
failureRedirect: '/auth/login/failed',
})
)
module.exports = { router, MAIN_PAGE_URL }
I want to log in with ajax.
I want user information to be recorded in the request parameter.
But when I do it with ajax, user information is not registered in the request parameter.
so req.user --> undefined
he's turning.
How can I solve this?
local auth passport codes:
const LocalStrategy = require("passport-local").Strategy;
const passport = require("passport");
const bcrypt = require("bcrypt");
const User = require("../models/User");
passport.use(
"user-login",
new LocalStrategy(
{
usernameField: "email",
},
(email, password, done) => {
User.findOne(
{
email,
},
(err, user) => {
if (err) return done(err, null, "Bir hata olustu");
if (!user) {
return done(null, false, "Böyle bir email yok.");
}
bcrypt.compare(password, user.password, (err, res) => {
if (res) {
return done(null, user, "Başarıyla giriş yapıldı.");
} else {
return done(null, false, "Yanlış şifre girildi");
}
});
}
);
}
)
);
passport.serializeUser(function (user, done) {
console.log(user);
done(null, user.id);
});
passport.deserializeUser(function (id, done) {
User.findById(id, function (err, user) {
console.log(user);
done(err, user);
});
});
router:
module.exports.postLogin = async (req, res, next) => {
passport.authenticate("user-login", {
successRedirect: "/",
failureRedirect: "/users/login",
failureFlash: true,
successFlash: true,
})(req, res, next);
}
app.js middleware
app.use((req, res, next) => {
console.log(req.user);
next();
});
print:
POST /admin/login 302 2304.994 ms - 23
{
_id: 5fb8fa8c26cdfc239c4276b9,
username: 'tolgaand',
password: '$2b$10$XhifEgbN4mEiCGPvm/dF5.zHYlEPZW3Jhibjm4ABuhEeRJ34psYsu',
name: 'Tolga',
lastName: 'Çağlayan',
title: 'Javascript Geliştiricisi',
about: "mongodb'ye bağlandım olley",
phone: '+90 534 393 6238',
email: 'tolgaand#yandex.com',
location: 'İstanbul / Türkiye',
available: 'Müsait',
permission: 0,
__v: 0
}
{}
router with ajax (i want)
module.exports.postLogin = async (req, res, next) => {
passport.authenticate("user-login", (error, user, info) => {
if (error) {
return res.json({ success: false, message: info.message });
}
if (!user) {
return res.json({ success: false, message: info });
}
res.json({ success: true, message: info, user });
})(req, res, next);
};
print:
POST /admin/login 200 998.327 ms - 446
undefined
{}
how can I do this with jquery / ajax?
instead of undefined, I just want user information to be registered as above.
I know variations of this questions have been asked multiple times. My understanding is that you basically have to watch your if/else logic and make sure that done isn't being called multiple times.
Twitter and Google work fine. Facebook is giving me this error though:
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
at ServerResponse.header (/Users/azerner/code/mean-starter/node_modules/express/lib/response.js:718:10)
at ServerResponse.location (/Users/azerner/code/mean-starter/node_modules/express/lib/response.js:835:8)
at ServerResponse.redirect (/Users/azerner/code/mean-starter/node_modules/express/lib/response.js:874:8)
at complete (/Users/azerner/code/mean-starter/node_modules/passport/lib/middleware/authenticate.js:241:26)
at /Users/azerner/code/mean-starter/node_modules/passport/lib/middleware/authenticate.js:250:15
at pass (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:427:14)
at Authenticator.transformAuthInfo (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:449:5)
at /Users/azerner/code/mean-starter/node_modules/passport/lib/middleware/authenticate.js:247:22
at /Users/azerner/code/mean-starter/node_modules/passport/lib/http/request.js:51:7
at pass (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:273:43)
at serialized (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:282:7)
at /Users/azerner/code/mean-starter/server/passport.js:17:5
at pass (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:290:9)
at Authenticator.serializeUser (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:295:5)
at IncomingMessage.req.login.req.logIn (/Users/azerner/code/mean-starter/node_modules/passport/lib/http/request.js:48:29)
passport.js
var LocalStrategy = require('passport-local').Strategy;
var FacebookStrategy = require('passport-facebook').Strategy;
var TwitterStrategy = require('passport-twitter').Strategy;
var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
var mongoose = require('mongoose');
var User = mongoose.model('User');
var Local = mongoose.model('Local');
var Facebook = mongoose.model('Facebook');
var Twitter = mongoose.model('Twitter');
var Google = mongoose.model('Google');
var bcrypt = require('bcrypt');
var config = require('./config.json');
module.exports = function(passport) {
passport.serializeUser(function(user, done) {
done(null, user._id);
});
passport.deserializeUser(function(id, done) {
User
.findById(id).populate('local').exec()
.then(function(user) {
console.log('deserializeUser found user: ', user);
done(null, user);
}, done)
;
});
// LOCAL
passport.use(new LocalStrategy(function(username, password, done) {
Local
.findOne({ username: username })
.select('username role hashedPassword')
.exec()
.then(function(local) {
if (!local) {
return done(null, false);
}
var validPassword = bcrypt.compareSync(password, local.hashedPassword);
if (!validPassword) {
return done(null, false);
}
else {
User
.findOne({ local: local })
.populate('local')
.exec()
.then(function(user) {
return done(null, user);
})
;
}
})
;
}));
// FACEBOOK
passport.use(new FacebookStrategy({
clientID: config.facebookAuth.clientID,
clientSecret: config.facebookAuth.clientSecret,
callbackURL: config.facebookAuth.callbackURL
}, function(token, refreshToken, profile, done) {
// asynchronous
process.nextTick(function() {
Facebook
.findOne({ id: profile.id })
.select('id token')
.exec()
.then(function(facebook) {
if (facebook) {
User
.findOne({ facebook: facebook._id }).exec()
.then(function(user) {
return done(null, user);
})
;
}
else {
Facebook
.create({ id: profile.id, token: token })
.then(function(createdFacebook) {
User
.create({ facebook: createdFacebook })
.then(function(user) {
return done(null, user);
})
;
})
;
}
})
.then(function(err) {
return done(err);
})
;
});
}));
// TWITTER
passport.use(new TwitterStrategy({
consumerKey: config.twitterAuth.consumerKey,
consumerSecret: config.twitterAuth.consumerSecret,
callbackURL: config.twitterAuth.callbackURL
}, function(token, tokenSecret, profile, done) {
process.nextTick(function() {
Twitter
.findOne({ id: profile.id })
.select('id token')
.exec()
.then(function(twitter) {
if (twitter) {
User
.findOne({ twitter: twitter._id }).exec()
.then(function(user) {
return done(null, user);
})
;
}
else {
Twitter
.create({ id: profile.id, token: token })
.then(function(createdTwitter) {
User
.create({ twitter: createdTwitter })
.then(function(user) {
return done(null, user);
})
;
})
;
}
})
.then(null, function(err) {
return done(err);
})
;
});
}));
// GOOGLE
passport.use(new GoogleStrategy({
clientID: config.googleAuth.clientID,
clientSecret: config.googleAuth.clientSecret,
callbackURL: config.googleAuth.callbackURL
}, function(token, refreshToken, profile, done) {
process.nextTick(function() {
Google
.findOne({ id: profile.id })
.select('id token')
.exec()
.then(function(google) {
if (google) {
User
.findOne({ google: google._id }).exec()
.then(function(user) {
return done(null, user);
})
;
}
else {
Google
.create({ id: profile.id, token: token })
.then(function(createdGoogle) {
User
.create({ google: createdGoogle })
.then(function(user) {
return done(null, user);
})
;
})
;
}
})
.then(null, function(err) {
return done(err);
})
;
});
}));
};
auth.routes.js
var mongoose = require('mongoose');
var express = require('express');
var passport = require('passport');
var Auth = require('./auth.service.js');
try {
var User = mongoose.model('User');
}
catch(e) {
var User = mongoose.model('User', require('../users/user.model.js').UserSchema);
}
var router = express.Router();
// LOCAL
router.post('/login', passport.authenticate('local'), function(req, res) {
res.status(200).json(req.user);
});
router.get('/logout', Auth.isLoggedIn, function(req, res) {
req.logout();
res.status(204).end();
});
router.get('/current-user', Auth.isLoggedIn, function(req, res) {
res.status(200).json(req.user);
});
// FACEBOOK
router.get('/auth/facebook', passport.authenticate('facebook'));
router.get('/auth/facebook/callback',
passport.authenticate('facebook', {
successRedirect: '/',
failureRedirect: '/login'
})
);
// TWITTER
router.get('/auth/twitter', passport.authenticate('twitter'));
router.get('/auth/twitter/callback',
passport.authenticate('twitter', {
successRedirect: '/',
failureRedirect: '/login'
})
);
// GOOGLE
router.get('/auth/google', passport.authenticate('google', { scope: ['profile'] }));
router.get('/auth/google/callback',
passport.authenticate('google', {
successRedirect: '/',
failureRedirect: '/login'
})
);
module.exports = router;
It's also worth noting that I have been using this to block Facebook, but I unblocked it to work on this. I did the commands, force quit Chrome and reopened it, and now I can log into facebook.com fine.
Edit: Oh, and I checked MongoHub and it shows that the User (and Facebook subdocument) have been created.