我使用Express-sessions和express-mysql-sessions。
用于身份验证的Passport.js:LocalStrategy,GoogleStrategy,FacebookStrategy
我在Google身份验证和Facebook身份验证方面有问题,这2个问题相同。
重定向到我的网站后,我无法获得
req.user
。
我正在寻找导致问题的原因,我知道了:
req.user
时,但是如果我重定向或重新加载页面,它将消失并返回到我以前的SessionID。 req.user
是未定义 因此,req.user中的数据已保存到新的SessionID,并且如果我重新加载页面或重定向,则我以前的SessionID和req.user是未定义的
我做错了吗?我在生产模式下的本地服务器上尝试了它,效果很好。但是当我在具有生产模式的Web托管服务器上尝试使用它时,
路线
routes.get('/auth/google',passport.authenticate("google",{
scope: ["profile", "email"]
}));
routes.get('/auth/google/redirect', passport.authenticate("google"),AuthController.googleRedirect);
routes.post('/auth/logout',AuthController.logout);
routes.get('/auth/facebook', passport.authenticate('facebook',{
scope: ["email"]
}));
routes.get('/auth/facebook/redirect', passport.authenticate('facebook'), AuthController.facebookRedirect);
回调重定向
export const googleRedirect = (req,res)=>{
//req.user is true
if (req.user) {
if (req.session.carts) {
console.log('I CAN SEE HERE');
return res.redirect(keys.origin.redirect);
}
console.log('I CAN SEE HERE');
return res.redirect(keys.origin.redictProfile);
}
else{
return res.status(400).json('INVALID');
}
}
Server.js
import express from "express";
import bodyParser from "body-parser";
import compression from "compression";
import morgan from "morgan";
import Loadable from "react-loadable";
import cookieParser from "cookie-parser";
import passport from "passport";
import session from "express-session";
import cors from "cors";
import passportSetup from "./config/passport-setup";
import keys from "./config/keys";
import uuidv4 from "uuid/v4";
import UAparser from "ua-parser-js";
import { ensureSession } from "./config/sessionCheck";
import sess from "express-mysql-session";
import csrf from 'csurf';
// // Our loader - this basically acts as the entry point for each page load
import loader from "./loader";
// SESSION
const MySQLStore = sess(session);
const optionSession = {
host: keys.database.host,
user: keys.database.user,
password: keys.database.password,
database: keys.database.database,
clearExpired: true,
checkExpirationInterval: 900000,
expiration: 86400000,
schema: {
tableName: "session",
columnNames: {
session_id: "id",
expires: "expires",
data: "data"
}
}
};
var sessionStore = new MySQLStore(optionSession);
// Create our express app using the port optionally specified
const app = express();
const PORT = process.env.PORT || 5000;
// Express Session
app.use(
session({
genid: function(req) {
return uuidv4(); // use UUIDs for session IDs
},
name: keys.session.name,
secret: keys.session.secret,
resave: false,
saveUninitialized: true,
store: sessionStore,
rolling: true,
cookie: {
secure: false,
httpOnly: true,
maxAge: keys.session.maxAge, // satu hari,
}
})
);
// Passport
app.use(passport.initialize());
app.use(passport.session());
app.disable("x-powered-by");
app.use(cors({ origin: keys.origin.url, credentials: true }));
// Compress, parse, log, and raid the cookie jar
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(morgan("dev"));
app.use(cookieParser());
if(process.env.NODE_ENV === 'production'){
app.use(compression());
app.use(csrf());
app.use(function (err, req, res, next) {
if (err.code !== 'EBADCSRFTOKEN') return next(err)
// handle CSRF token errors here
res.status(403)
res.send('INVALID TOKEN')
})
}
app.use((req, res, next) => {
res.header("X-XSS-Protection", "1; mode=block");
res.header("X-Frame-Options", "deny");
res.header("X-Content-Type-Options", "nosniff");
res.header("Access-Control-Allow-Origin", keys.origin.url);
console.log(req.sessionID)
next();
});
app.use("/api/", ensureSession, [
AuthRoutes,
]);
app.use("/v1/", [v1Routes]);
// Production Mode
if (process.env.NODE_ENV === "production") {
// Set up homepage, static assets, and capture everything else
app.use(express.Router().get("/", loader));
app.use(express.static(path.resolve(__dirname, "../build")));
app.use(loader);
Loadable.preloadAll().then(() => {
app.listen(PORT, console.log(`App listening on port ${PORT}!`));
});
}
护照设置
passport.serializeUser((user, done) => {
let tokenValue = {
}
if (user.providerId) tokenValue.providerId = user.providerId;
if (user.token) tokenValue.token = user.token;
if (user.provider) tokenValue.provider = user.provider;
if (user.id) tokenValue.user_id = user.id;
if (user.email) tokenValue.email = user.email;
console.log('serializeUser-data',user);
console.log('serializeUser-token',tokenValue);
done(null, tokenValue)
})
passport.deserializeUser((data, done) => {
console.log('DESERIALIZEUSER-data',data);
let querySelect = `SELECT
us.id,
us.displayName,
us.email,
us.gender,
up.providerId,
up.token,
up.provider,
us.firstname,
us.lastname,
ui.birthday,
ui.phone_number from user as us
left join user_provider as up on us.id = up.user_id
left join user_information as ui on us.id = ui.user_id
where us.id = ? `;
db.query(querySelect, [data.user_id], (err, ress) => {
if (ress.length > 0) {
console.log('DESERIALIZEUSER',ress[0]);
done(null, ress[0])
}
});
})
passport.use('local-signup', new LocalStrategy(
{
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true // allows us to pass back the entire request to the callback
},
function (req, email, password, done) {
let queryFindUser = `SELECT email from user_account where email = ?;SELECT email from user where email = ? and is_provider = 1;`;
db.query(queryFindUser, [req.body.email, req.body.email], (err, result) => {
if (err) return done(null,false, { error: true, message: "ERROR FROM REGISTER" });
if (result[0].length > 0) {
return done(null, false,{ error: true, message: "Email is already registered" });
}
if (result[1].length > 0) {
return done(null, false, { error: true, message: "Email is already registered using social media" });
}
if(result[0].length === 0 && result[1].length === 0){
let queryInsert = 'INSERT into user set ?; INSERT into user_account set user_id = (select u.id from user as u order by u.id desc limit 1), ?;';
// let querySelectUser = `INSERT `
bcrypt.genSalt(10, (err, salt) => {
//10 adalah berapa banyak karakter
bcrypt.hash(req.body.password, salt, (err, hash) => {
if (err) {
throw err;
}
if (hash) {
db.query(queryInsert, [{ displayName: req.body.displayName, email: req.body.email }, { email: req.body.email, password: hash }], (err, result) => {
if (err) return done(null, false, { error: true, message: "ERROR FROM REGISTER" });
if (result) {
let querySelect = `SELECT
us.id,
us.displayName,
us.email,
us.gender,
up.providerId,
up.token,
up.provider,
us.firstname,
us.lastname,
ui.birthday,
ui.phone_number from user as us
left join user_provider as up on us.id = up.user_id
left join user_information as ui on us.id = ui.user_id
where us.id = ? `;
db.query(querySelect, [result[0].insertId], (err, ress) => {
if (ress.length > 0) {
return done(null, ress[0])
} else {
return done(null, false, { error: true, message: "error from register" });
}
})
}
})
}
});
});
}
}
}
));
passport.use(new LocalStrategy(
function (email, password, done) {
let querySelect = `SELECT
us.id,
us.displayName,
us.gender,
us.firstname,
us.lastname,
ui.birthday,
ui.phone_number,
ua.email,
ua.password,
ua.email_confirm_token
from user as us
left join user_account as ua on us.id = ua.user_id
left join user_information as ui on us.id = ui.user_id
where ua.email = ?
`
db.query(querySelect, [email], (err, result) => {
if (err) return done(err, null);
if (result.length > 0) {
let data = result[0];
bcrypt.compare(password, data.password)
.then(isMatch => {
if (isMatch) {
return done(null, data);
} else {
return done(null, false, { message: 'Incorrect password.' });
}
})
}
if (result.length === 0) {
return done(null, false, { message: 'Incorrect email.' });
}
})
}
));
passport.use(
new GoogleStrategy({
//options for the google strategy
callbackURL: keys.origin.redirectProvider + '/api/auth/google/redirect',
clientID: keys.google.clientID,
clientSecret: keys.google.clientSecret,
userProfileURL: 'https://www.googleapis.com/oauth2/v3/userinfo'
}, (accessToken, refreshToken, profile, done) => {
let queryInsert = `INSERT INTO user set is_provider = 1, ?; INSERT INTO user_provider set user_id = (SELECT u.id from user as u order by id desc limit 1), ?;`;
let queryUpdate = `update user_provider set token = ? where providerId = '${profile.id}'`;
let queryFind = `SELECT
us.id,
us.displayName,
us.email,
us.gender,
up.providerId,
up.token,
up.provider,
us.firstname,
us.lastname,
ui.birthday,
ui.phone_number
from user as us
left join user_provider as up on us.id = up.user_id
left join user_information as ui on us.id = ui.user_id
where up.providerId = '${profile.id}' and up.provider = '${profile.provider}' and us.is_provider = 1`;
let querySelect = `SELECT
us.id,
us.displayName,
us.email,
us.gender,
up.providerId,
up.token,
up.provider,
us.firstname,
us.lastname,
ui.birthday,
ui.phone_number from user as us
left join user_provider as up on us.id = up.user_id
left join user_information as ui on us.id = ui.user_id
where us.id = ? and up.provider = ? and up.providerId = ? and us.is_provider = 1`;
const querySelectAfterUpdate = `SELECT
us.id,
us.displayName,
us.email,
us.gender,
up.providerId,
up.token,
up.provider,
us.firstname,
us.lastname,
ui.birthday,
ui.phone_number from user as us
left join user_provider as up on us.id = up.user_id
left join user_information as ui on us.id = ui.user_id
where up.provider = ? and up.providerId = ? and us.is_provider = 1`;
let user = {
email: profile.emails[0].value,
}
if (profile.gender) user.gender = profile.gender;
if (profile.displayName) user.displayName = profile.displayName;
if (Object.keys(profile.name).length > 0) {
if (profile.name.familyName) user.lastname = profile.name.familyName;
if (profile.name.givenName) user.firstname = profile.name.givenName;
}
let user_provider = {
provider: profile.provider,
providerId: profile.id,
token: refreshToken ? refreshToken : accessToken
}
db.query(queryFind, (error, result) => {
if (error) return done(error);
if (result.length > 0) {
console.log('user', result);
db.query(queryUpdate, [user_provider.token], (err, ress)=>{
console.log('res',ress);
if (err) return done(err);
if (ress.affectedRows > 0) {
db.query(querySelectAfterUpdate, [profile.provider, profile.id], (err, ress) => {
if (err) return done(err);
if (ress.length > 0) {
return done(null, ress[0]);
}
})
}
if (ress.affectedRows === 0){
return done(null, result[0]);
}
})
} else {
db.query(queryInsert, [user, user_provider], (err, ress, fields) => {
if (err) return done(err);
if (ress) {
db.query(querySelect, [ress[0].insertId, profile.provider, profile.id], (err, ress) => {
if (err) return done(err);
if (ress.length > 0) {
return done(null, ress[0]);
}
})
}
})
}
})
})
);