如何正确使用passport.js

我正在尝试使用护照库来validationAPI请求。 要开始,我已经创build了一个NodeJS应用程序与快速框架。 该项目包含一些提供某些数据的apis。 在公共文件夹中,它包含具有用户名和密码字段的index.html页面。

的index.html

<form action="/login" method="post"> <div> <label>Username:</label> <input type="text" name="name"/> </div> <div> <label>Password:</label> <input type="password" name="password"/> </div> <div> <input type="submit" value="Log In"/> </div> </form> 

创build一个server.ts ,创build一个http服务器,并监听某个端口,并使用express框架创buildapis。

Server.ts

 let userList: User[] = [new User(1, "Sunil"), new User(2, "Sukhi")]; let app = express(); // passport library let passport = require('passport'); let LocalStrategy = require('passport-local').Strategy; // middlewares app.use(express.static("public")); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(session({ resave: false, saveUninitialized: true, secret: "secretKey123!!" })); // passport middleware invoked on every request to ensure session contains passport.user object app.use(passport.initialize()); // load seriliazed session user object to req.user app.use(passport.session()); // Only during the authentication to specify what user information should be stored in the session. passport.serializeUser(function (user, done) { console.log("Serializer : ", user) done(null, user.userId); }); // Invoked on every request by passport.session passport.deserializeUser(function (userId, done) { let user = userList.filter(user => userId === user.userId); console.log("D-serializer : ", user); // only pass if user exist in the session if (user.length) { done(null, user[0]); } }); // passport strategy : Only invoked on the route which uses the passport.authenticate middleware. passport.use(new LocalStrategy({ usernameField: 'name', passwordField: 'password' }, function (username, password, done) { console.log("Strategy : Authenticating if user is valid :", username) let user = userList.filter(user => username === user.userName) if (!user) { return done(null, false, { message: 'Incorrect username.' }); } return done(null, user); } )); app.post('/login', passport.authenticate('local', { successRedirect: '/done', failureRedirect: '/login' })); app.get('/done', function (req, res) { console.log("Done") res.send("done") }) app.get('/login', function (req, res) { console.log("login") res.send("login") }) // http server creation let server = http.createServer(app); server.listen(7000, () => { console.log('Up and running on port 7000'); }); 

现在,当我打本地主机:7000它打开login页面,当我点击提交用户名从userList它返回完成否则login。 这可以。

现在每个调用都经过deserializeUser方法。

问题是,当我打电话给其他URL直接不敲击/login(身份validation用户)他们也很好地工作,并返回数据。

我期待,如果请求未通过身份validation所有其他调用将失败,因为deserializeUser拦截每个请求,但在这种情况下,没有护照方法被调用。

这是如何工作的? 或者我错过了什么?

您需要添加一个中间件,以检查您的用户是否已通过身份validation:

 isAuthenticated = (req, res, next) => { if (req.isAuthenticated()) { //if user is logged in, req.isAuthenticated() will return true return next(); } res.redirect('/login'); }; 

你必须使用这样的中间件:

 //if user not authenticated, he will be redirect on /login app.get('/done', isAuthenticated, (req, res) => { res.send("done") }); 

我错过了中间件来validation所有后续的请求。 所以我创build了isAuthenticated方法(谢谢@Sombrero)。

 // request interceptor that will check user authentication private static isAuthenticated = (req, res, next) => { console.log("Authenticating :", req.originalUrl) if (req.isAuthenticated()) { return next(); } res.redirect('/login'); }; 

然后在每个请求

 app.get('/done', isAuthenticated, (req, res) => { res.send("done") }); 

但是在每个请求中都很难使用isAuthenticated方法。 所以我创build了一个公开的API列表,并添加了中间件来拦截每个请求,并更新了isAuthenticated方法来忽略公共apis

 // list of apis for which authentication is not required private static publicApiList: string[] = ["/login"]; // request interceptor that will check user authentication private static isAuthenticated = (req, res, next) => { console.log("Authenticating :", req.originalUrl) if (req.isAuthenticated() || Server.publicApiList.indexOf(req.originalUrl) > -1) { return next(); } res.redirect('/login'); }; 

然后用这个方法作为中间件

 app.use(Server.isAuthenticated)