如果我添加创建会话的序列化/反序列化 Passportjs 方法,下面的代码将完美运行。我正在努力创建 Json Web 令牌,而不是会话。任何教程、建议或清晰的示例将不胜感激。我使用nodejs。
我了解了智威汤逊如何运作的赞成/反对和基本概述。我是从以下来源了解到的。
/
没有 JWT 代码
var express = require("express"),
path = require("path"),
bodyParser = require("body-parser"),
mysql = require("mysql"),
connection = require("express-myconnection"),
morgan = require("morgan"),
app = express(),
passport = require("passport"),
GoogleStrategy = require("passport-google-oauth").OAuth2Strategy;
app.use(passport.initialize());
app.get("/", function(req, res) {
res.sendFile(__dirname + "/public/main.html");
});
// #1
passport.use(
new GoogleStrategy({
clientID: "32434m",
clientSecret: "23434",
callbackURL: "http://localhost:3000/auth/google/callback"
},
function(accessToken, refreshToken, profile, done) {
process.nextTick(function() {
console.log("profile.id: " + profile.id);
return done(null, profile.id); // that is being serealized(added in session)
});
}
)
);
// #1
app.get("/auth/google",
passport.authenticate(
"google", {
scope: ["profile", "email"]
}));
// #2
app.get("/auth/google/callback",
passport.authenticate("google", {
failureRedirect: "/google_callback_fail",
successRedirect: "/google_callback_success"
})
);
app.get("/google_callback_success", isLoggedIn, function(req, res) {
res.send("google_callback_success \n");
});
function isLoggedIn(req, res, next) {
console.log("isLoggedIn req.user: " + req.user);
if (req.isAuthenticated()) {
console.log("isAuthenticated TRUE");
return next();
}
res.redirect("/notloggedin");
}
app.get("/notloggedin", function(req, res) {
console.log("req.user: " + req.user);
res.json("not loggedin");
});
app.get("/google_callback_fail", function(req, res) {
res.json("the callback after google DID NOT authenticate the user");
});
app.listen(3000);
JWT 代码尝试。问题是我需要添加序列化/反序列化,但我不想添加序列化/反序列化,因为我不想使用会话。我要智威汤逊
var express = require("express"),
path = require("path"),
bodyParser = require("body-parser"),
mysql = require("mysql"),
connection = require("express-myconnection"),
morgan = require("morgan"),
app = express(),
passport = require("passport"),
GoogleStrategy = require("passport-google-oauth").OAuth2Strategy,
jwt = require('jsonwebtoken'),
passportJWT = require("passport-jwt"),
ExtractJwt = require('passport-jwt').ExtractJwt,
JwtStrategy = require('passport-jwt').Strategy;
var jwtOptions = {};
jwtOptions.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
jwtOptions.secretOrKey = 'secret';
app.use(passport.initialize());
app.get("/", function(req, res) {
res.sendFile(__dirname + "/public/main.html");
});
// #1
passport.use(
new GoogleStrategy({
clientID: "s-s.apps.googleusercontent.com",
clientSecret: "23redsf",
callbackURL: "http://localhost:3000/auth/google/callback"
},
function(accessToken, refreshToken, profile, done) {
process.nextTick(function() {
console.log("\nprofile.id: " + profile.id);
return done(null, profile.id); // that is being serealized(added in session)
});
}
)
);
// #1
app.get(
"/auth/google",
passport.authenticate(
"google", {
scope: ["profile", "email"]
}
)
);
// #2
app.get(
"/auth/google/callback",
passport.authenticate("google", {
failureRedirect: "/google_callback_fail",
successRedirect: "/google_callback_success"
})
);
app.get("/google_callback_success", isLoggedIn, function(req, res) {
var payload = { id: user.id };
var token = jwt.sign(payload, jwtOptions.secretOrKey);
var strategy = new JwtStrategy(jwtOptions, function(jwt_payload, next) {
console.log('payload received', jwt_payload);
console.log('jwt_payload.id: ' + jwt_payload.id);
});
passport.use(strategy);
res.send("google_callback_success \n" + 'token: ' + token);
});
function isLoggedIn(req, res, next) {
console.log("isLoggedIn req.user: " + req.user);
if (req.isAuthenticated()) {
console.log("isAuthenticated TRUE");
var payload = { id: user.id };
var token = jwt.sign(payload, jwtOptions.secretOrKey);
console.log('token: ' + token);
return next();
}
res.redirect("/notloggedin");
}
app.get("/notloggedin", function(req, res) {
console.log("req.user: " + req.user);
res.json("not loggedin");
});
app.get("/google_callback_fail", function(req, res) {
res.json("the callback after google DID NOT authenticate the user");
});
app.get("/logout", function(req, res) {
console.log("logged out");
req.logout();
res.redirect("/logout");
});
app.listen(3000);
代码
return done(null, profile.id); // that is being serialized(added in session)
就是问题所在。我应该用什么来替换它,这样我就不必使用会话?我想用 JWT 替换它。
https://www.sitepoint.com/spa-social-login-google-facebook/
基本上在谷歌身份验证完成后,您为用户创建一个jwt。
// src/index.js
function generateUserToken(req, res) {
const accessToken = token.generateAccessToken(req.user.id);
res.render('authenticated.html', {
token: accessToken
});
}
app.get('/api/authentication/google/start',
passport.authenticate('google', { session: false, scope:
['openid', 'profile', 'email'] }
));
app.get('/api/authentication/google/redirect',
passport.authenticate('google', { session: false }),
generateUserToken
);
经过很长时间寻找解决方法,我终于遇到了这个问题。迄今为止最好的选择,非常适合我。
app.get('/auth/google/callback',
passport.authenticate('google',
{ failureRedirect: '/', session: false }), (req, res) => {
const jwt = createJWTFromUserData(req.user);
const htmlWithEmbeddedJWT = `
<html>
<script>
// Save JWT to localStorage
window.localStorage.setItem('JWT', '${jwt}');
// Redirect browser to root of application
window.location.href = '/';
</script>
</html>
`;
res.send(htmlWithEmbeddedJWT);
});
这可以通过在新窗口中打开 google auth 屏幕并使用
window.postMessage()
写回 JWT 来实现。
应用程序:
const Login = () => {
const setToken = function(e) {
if (
e.origin === origin &&
e.data &&
e.data.command === 'token-ready' &&
e.data.info &&
e.data.info.token
) {
localStorage.setItem('jwt', e.data.info.token);
e.source.postMessage(
{
command: 'info',
info: {
complete: true,
},
},
e.origin
);
}
};
window.addEventListener('message', setToken, false);
const login = () => {
window.open(loginUri);
};
return (<button onClick={login}>Login</button>
}
服务器响应:
const html = `
<!DOCTYPE html>
<html>
<head>
<title>Authenticated</title>
</head>
<body>
Authenticated successfully.
<script type="text/javascript">
window.addEventListener("message", function(e) {
console.dir(e)
if (e.origin === "${postBackUri}" && e.data && e.data.info && e.data.info.complete) {
window.close();
}
}, false);
opener.postMessage({
command: "token-ready",
info: {
token: "${token}",
},
}, "${postBackUri}");
</script>
</body>
</html>
`;
return res.send(html);
这对你有用
app.get('/google',passport.authenticate('google',{scope:['profile']}));
// callback google
app.get('/google/callback',passport.authenticate('google',
{session:false,failureRedirect:'/login/failed'}),(req,res)=>{
// generate new access token
const acc = GenerateAccessToken(req.user);
res.cookie('au_ac',acc,{httpOnly:true});
return res.redirect(CLIENT_URL)
});
这里验证token
app.get('/is/authenticated',async(req,res)=>{
const {au_ac} = req.cookies ;
if(!au_ac) return res.json({authenticated:false});
try{
const user = await Verify_Access_Token(au_ac);
return res.json({user,authenticated:true})
}catch(err){
return res.status(401).json({authenticated:false})
}
});
这是一个简单的示例,您的应用程序还应该具有刷新令牌。
看看Passport-JWT。正如他们所说,该模块允许您使用 JSON Web 令牌对端点进行身份验证。它旨在用于保护没有会话的 RESTful 端点。