我正在使用 PassportJS 在 NextJS 应用程序上通过 Google 对用户进行身份验证。到目前为止,我的身份验证部分工作正常。但是,Google 坚持要我向它注册一个回调 URL或其列表,并在登录成功后仅将用户重定向到其中一个。
我想要的是让它充满活力。因此,如果用户在https://www.schandillia.com/blog/somepage上并通过 Google 按钮点击登录,他首先会转到https://www.shandillia.com/auth/google,然后转到https: //accounts.google.com/signin/oauth/oauthchooseaccount。在这里,一旦他成功登录(甚至不成功),我希望他被带回https://www.schandillia.com/blog/somepage,而不是一些静态重定向页面。我的 repo 位于https://github.com/amitschandillia/proost/tree/master/web并且有问题的脚本如下:
/server/server.js
import express from 'express';
import cookieParser from 'cookie-parser';
import bodyParser from 'body-parser';
import next from 'next';
import authRoutes from '../routes/auth-routes';
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
dotenv.config();
app.prepare().then(() => {
const server = express();
// Custom middleware
// ---------------------------------------------------------------------
server.use(bodyParser.json());
server.use(bodyParser.urlencoded({ extended: false }));
server.use(cookieParser());
// ---------------------------------------------------------------------
// Auth routes
// ---------------------------------------------------------------------
server.use('/auth', authRoutes);
// ---------------------------------------------------------------------
// Default route (not to be edited)
// ---------------------------------------------------------------------
server.get('*', (req, res) => handle(req, res));
// ---------------------------------------------------------------------
// Express: Listener
server.listen(process.env.WEB_PORT, () => {
/* eslint-disable no-console */
console.log(`>> Listening on port ${process.env.WEB_PORT}`);
/* eslint-enable no-console */
});
}).catch((ex) => {
console.error(ex.stack);
process.exit(1);
});
/routes/auth-routes.js
import express from 'express';
import passport from 'passport';
import passportSetup from '../config/passport-setup';
const router = express.Router();
// auth login
router.get('/login', (req, res) => {
res.send('login...');
});
// auth logout
router.get('/logout', (req, res) => {
res.send('log out...');
});
// auth with Google
router.get('/google', passport.authenticate('google', {
scope: ['profile']
}));
module.exports = router;
/config/passport-setup.js
import passport from 'passport';
import GoogleStrategy from 'passport-google-oauth20';
dotenv.config();
passport.use(
new GoogleStrategy({
// options for google strategy
callbackURL: 'https://www.schandillia.com/auth/google/redirect',
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
}, () => {
// passport callback function
}),
);
然后,按照 NextJS 世界的惯例,我将我的页面定义为/pages/
. 登录功能本身是通过Navbar.jsx
组件在所有页面上可用的模式对话框而不是专用登录页面。
那么,如何将当前 URL 值从客户端/config/passport-setup.js
动态传递给脚本?此外,Google 是否对可以添加到回调列表的 URL 数量有限制?
PS:我尝试使用universal-cookie在以下位置设置cookie(如nm在下面的评论中所建议)pages/index.jsx
:
const cookies = new Cookies();
然后在中设置值componentDidMount()
:
pageURL = process.env.BASE_URL + Router.pathname; // https://schandillia.com/
const cookies = new Cookies();
cookies.set('pageURL', pageURL);
这成功地设置了cookie。然后要检索相同的内容,我在我的中执行以下操作server.js
:
// Cookie
server.use(function (req, res, next) {
// check if client sent cookie
const pageURL = req.cookies.pageURL;
if (pageURL === undefined) {
console.log('NO COOKIE FOUND!!');
}
else {
console.log('COOKIE FOUND!!!!', pageURL);
}
next();
});
该系统运行良好。客户端路由期间除外。由于服务器仅在页面最初加载或刷新时才被调用,因此当路由严格发生在浏览器上时,它无法接收 cookie。任何解决方法?