我一直在尝试使用快速会话和通行证设置Nextjs应用程序,我设法登录并将结果保存到Redis中,然后我现在的目标是能够从任何地方访问req.user想要(在所有请求中)。我的问题是,登录后我将用户和处理来自下一个路由系统的所有请求的控制器重定向,似乎无法从请求中获取用户(给出未定义的信息)...
有我的自定义服务器:
import dotenv from 'dotenv';
dotenv.config();
import next from 'next';
import express from 'express';
import cors from 'cors';
import chalk from 'chalk';
import passport from 'passport';
import bodyParser from 'body-parser';
import sessionMiddleware from './middleware/sessionMiddleware';
import passportSetup from './utils/passport';
import proxyConfigs from './proxyConfigs';
import Logger from './utils/logger';
import Router from './controllers';
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
const port = parseInt(`${process.env.PORT}`, 10) || 3000;
app.prepare().then(() => {
const server = express();
server.use(bodyParser.json());
server.use(cors());
server.use(sessionMiddleware);
passportSetup(passport);
server.use(passport.initialize());
server.use(passport.session());
server.use('/api', proxyConfigs);
server.disable('x-powered-by');
Router(server, handle, passport);
server.listen(port, (err: Error) => {
if (err) throw err;
Logger({
message: `Server is running on: ${chalk.blue(
`${process.env.HOST || 'http://localhost'}:${port}`
)}`,
level: 'info',
});
});
});
我的身份验证控制器:
import { Router, Server, Response, NextFunction } from 'express';
import { SCOUser } from 'server/types/custom';
import { PassportStatic } from 'passport';
import { PASSPORT_LOCAL_STRATEGY_NAME } from '../../configs/constants';
export default (server: Server, passport: PassportStatic) => {
const authRouter = Router();
authRouter.post('/login', (req: any, res: Response, next: NextFunction) => {
try {
passport.authenticate(PASSPORT_LOCAL_STRATEGY_NAME, (_err, user: SCOUser, info) => {
req.login(user, (loginError: string) => {
if (loginError) {
res.status(401);
if (info) {
res.json(info);
}
return res.end();
}
console.log(req.user);
return res.status(200).json(user.data);
});
})(req, res, next);
} catch (error) {
return res.status(500);
}
});
server.use('/auth', authRouter);
};
我的会话中间件:
import { Request, Response, NextFunction } from 'express';
import session from 'express-session';
import * as uuid from 'uuid';
import redisStore from 'connect-redis';
import { REDIS_SECRET } from '../../configs/constants';
import Redis from '../entities/Redis';
const RedisStore = redisStore(session);
export default (_req: Request, _res: Response, next: NextFunction) => {
const genid: string = uuid.v4();
session({
genid: () => genid,
secret: REDIS_SECRET,
store: new RedisStore({
client: Redis.client,
}),
resave: true,
saveUninitialized: true,
cookie: {
secure: false,
},
});
next();
};
我的护照配置(缺少解析用户数据的功能):
import { PassportStatic } from 'passport';
import * as passportLocal from 'passport-local';
import chalk from 'chalk';
import { REDIS_SESSION_KEY_PREFIX, PASSPORT_LOCAL_STRATEGY_NAME } from '../../configs/constants';
import Redis from '../entities/Redis';
import Logger from '../utils/logger';
import serverAxiosInstances from '../../configs/serverAxiosInstances';
import { SCOUser, SCOContract, SCOModule, SCOAccesses } from 'server/types/custom';
export default (passport: PassportStatic) => {
const LocalStrategy = passportLocal.Strategy;
passport.use(
PASSPORT_LOCAL_STRATEGY_NAME,
new LocalStrategy(
{ usernameField: 'email', passwordField: 'password' },
async (email, password, done) => {
try {
const response = await serverAxiosInstances.authApi.post(
`/authenticate`, { email, password }
);
if (response.status && response.status === 200) {
const user = parseUser(response.data);
Logger({
message: chalk.blue(`User ${user.data.userKey} successfully logged in.`),
level: 'info',
});
await Redis.setAsync(
`${REDIS_SESSION_KEY_PREFIX}:${user.data.userKey}`,
JSON.stringify(user)
);
done(null, user);
}
} catch (error) {
return done(null, false, {
message: error,
});
}
}
)
);
passport.serializeUser((user: SCOUser, done) => {
done(null, user.data.userKey);
});
passport.deserializeUser(async (key, done) => {
try {
const res = await Redis.getAsync(`${REDIS_SESSION_KEY_PREFIX}:${key}`);
done(null, res);
} catch (error) {
done(null, error);
}
});
};
最后是server.all中的NextJs路由处理程序。我要在其中使用req.user:
import { Response, Server } from 'express';
export default (server: Server, handle: Function) => {
server.all('*', (req: any, res: Response) => {
const user = req.user && typeof req.user === 'string' ? JSON.parse(req.user) : req.user;
console.log('user', user);
handle(req, res);
});
};