Passport & JWT & Google 策略 - 在 google 回调后禁用会话 & res.send()
Passport & JWT & Google Strategy - Disable session & res.send() after google callback
我想使用 JWT with Google login - for that I need to disable session 并以某种方式将用户模型传递回客户端。
所有示例都使用 google 回调 magically redirect to '/'.
我如何:
1. 使用 passport-google-oauth2.
时禁用会话
2. res.send() 用户到客户端 google 认证后。
如果我的方向不对,请随时提出替代方案。
通过一些见解设法克服这个问题:
1. 在 express 中禁用会话 - 只需删除会话的中间件
// app.use(session({secret: config.secret}))
2。当使用 Google 身份验证时,实际发生的是重定向到 google 登录页面,如果登录成功,它会将您重定向回您提供的 url。
这实际上意味着一旦 google 调用你的回调,你就不能 res.send(token, user) - 它根本不起作用(任何人都可以详细说明为什么?)。因此,您被迫通过 res.redirect("/")
重定向到客户端。
但整个目的是传递令牌,因此您也可以执行 res.redirect("/?token=" + token)
.
app.get( '/auth/google/callback',
passport.authenticate('google', {
//successRedirect: '/',
failureRedirect: '/'
, session: false
}),
function(req, res) {
var token = AuthService.encode(req.user);
res.redirect("/home?token=" + token);
});
但是客户端如何获取用户实体呢?
所以你也可以用同样的方式传递用户,但我觉得不合适(在参数列表中传递整个用户实体......)。
所以我所做的是让客户端使用令牌并检索用户。
function handleNewToken(token) {
if (!token)
return;
localStorageService.set('token', token);
// Fetch activeUser
$http.get("/api/authenticate/" + token)
.then(function (result) {
setActiveUser(result.data);
});
}
这意味着另一个 http 请求 - 这让我觉得我可能没有理解令牌的概念。
不吝赐教。
在index.js初始化护照:
app.use(passport.initialize());
在您的 passport.js 文件中:
passport.use(
new GoogleStrategy(
{
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL:
'http://localhost:3000/auth/google/redirect',
},
async (accessToken, refreshToken, profile,
callback) => {
// Extract email from profile
const email = profile.emails![0].value;
if (!email) {
throw new BadRequestError('Login failed');
}
// Check if user already exist in database
const existingUser = await User.findOne({ email
});
if (existingUser) {
// Generate JWT
const jwt = jwt.sign(
{ id: existingUser.id },
process.env.JWT_KEY,
{ expiresIn: '10m' }
);
// Update existing user
existingUser.token = jwt
await existingUser.save();
return callback(null, existingUser);
} else {
// Build a new User
const user = User.build({
email,
googleId: profile.id,
token?: undefined
});
// Generate JWT for new user
const jwt = jwt.sign(
{ id: user.id },
process.env.JWT_KEY,
{ expiresIn: '10m' }
);
// Update new user
user.token = jwt;
await auth.save();
return callback(null, auth);
}
}));
通过 req.user
在路由中接收此 JWT
app.get('/google/redirect', passport.authenticate('google',
{failureRedirect: '/api/relogin', session: false}), (req, res) => {
// Fetch JWT from req.user
const jwt = req.user.token;
req.session = {jwt}
// Successful authentication, redirect home
res.status(200).redirect('/home');
}
我想使用 JWT with Google login - for that I need to disable session 并以某种方式将用户模型传递回客户端。
所有示例都使用 google 回调 magically redirect to '/'.
我如何:
1. 使用 passport-google-oauth2.
时禁用会话
2. res.send() 用户到客户端 google 认证后。
如果我的方向不对,请随时提出替代方案。
通过一些见解设法克服这个问题:
1. 在 express 中禁用会话 - 只需删除会话的中间件
// app.use(session({secret: config.secret}))
2。当使用 Google 身份验证时,实际发生的是重定向到 google 登录页面,如果登录成功,它会将您重定向回您提供的 url。
这实际上意味着一旦 google 调用你的回调,你就不能 res.send(token, user) - 它根本不起作用(任何人都可以详细说明为什么?)。因此,您被迫通过 res.redirect("/")
重定向到客户端。
但整个目的是传递令牌,因此您也可以执行 res.redirect("/?token=" + token)
.
app.get( '/auth/google/callback',
passport.authenticate('google', {
//successRedirect: '/',
failureRedirect: '/'
, session: false
}),
function(req, res) {
var token = AuthService.encode(req.user);
res.redirect("/home?token=" + token);
});
但是客户端如何获取用户实体呢? 所以你也可以用同样的方式传递用户,但我觉得不合适(在参数列表中传递整个用户实体......)。 所以我所做的是让客户端使用令牌并检索用户。
function handleNewToken(token) {
if (!token)
return;
localStorageService.set('token', token);
// Fetch activeUser
$http.get("/api/authenticate/" + token)
.then(function (result) {
setActiveUser(result.data);
});
}
这意味着另一个 http 请求 - 这让我觉得我可能没有理解令牌的概念。 不吝赐教。
在index.js初始化护照:
app.use(passport.initialize());
在您的 passport.js 文件中:
passport.use(
new GoogleStrategy(
{
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL:
'http://localhost:3000/auth/google/redirect',
},
async (accessToken, refreshToken, profile,
callback) => {
// Extract email from profile
const email = profile.emails![0].value;
if (!email) {
throw new BadRequestError('Login failed');
}
// Check if user already exist in database
const existingUser = await User.findOne({ email
});
if (existingUser) {
// Generate JWT
const jwt = jwt.sign(
{ id: existingUser.id },
process.env.JWT_KEY,
{ expiresIn: '10m' }
);
// Update existing user
existingUser.token = jwt
await existingUser.save();
return callback(null, existingUser);
} else {
// Build a new User
const user = User.build({
email,
googleId: profile.id,
token?: undefined
});
// Generate JWT for new user
const jwt = jwt.sign(
{ id: user.id },
process.env.JWT_KEY,
{ expiresIn: '10m' }
);
// Update new user
user.token = jwt;
await auth.save();
return callback(null, auth);
}
}));
通过 req.user
在路由中接收此 JWTapp.get('/google/redirect', passport.authenticate('google',
{failureRedirect: '/api/relogin', session: false}), (req, res) => {
// Fetch JWT from req.user
const jwt = req.user.token;
req.session = {jwt}
// Successful authentication, redirect home
res.status(200).redirect('/home');
}