@FunC
2018-03-26T19:09:31.000000Z
字数 1866
阅读 4862
JavaScript
passport.js 是用来实现 authenticate/authorize 的中间件。
鉴于官网文档里都是一些代码片段,没有 API 的详细说明,这里整理一些需要注意的点。
passport.initialize()
初始化 passport.js 的配置。如果需要持久化的登陆session,还需要调用中间件 passport.session()
。中间件的顺序应为:express-session -> passport.initialize -> passport.session
passport.serializeUser()
和 passport.deserializeUser()
(作用见下文)passport.authenticate()
的路由主要参考自 http://toon.io/understanding-passportjs-authentication-flow/
以在路由 /login
上进行认证为例
1. 用户 POST 一个登陆表单,导致中间件 passport.authenticate
的执行
2. 调用相应的认证策略,这里因为是用 username 和 password 进行登陆,所以使用 local
策略(由npm packagepassport-local
提供)
3. Passport 获取 req.body.username
和 req.body.password
,用作验证策略的参数(需要提前配置 body-parser
)
4. 从数据库取出相应的 user 对象,验证密码
5. 如果验证通过,passport 内部自动调用 req.login()
,用于建立登陆session。
6. req.login()
会调用我们先前定义的 passport.serializeUser()
,该方法决定将 user 实例的哪些数据存入 session,一般选择存 user.id
。passport.serializeUser()
将设置 req.session.passpot.user = {/* serialized user object */}
7. 然后将 user 实例挂载到 req.user
上
8. 之后执行常规的 requestHandler
通过认证之后,发来的请求会经过下面的步骤:
1. Express 加载 session 的数据,并将其挂载在 req
上。
2. 先前配置的 passport.initialize
中间件会发现 session 中有 passport.user
的数据。如果没有则创建一个 req.passport.user = {}
3. 随后触发 passport.session
中间件,它本质上是一个名为 “session” 的认证策略,通过 session 存储的 user data,根据先前定义的 passport.deserializeUser
方法,从数据库中取出相应的 user 实例,并重新挂载在 ·req.user` 上
passport.authenticate('local')
方法的核心是从 req.body
中获取用户名和密码,并进行验证。所以只能用在 POST 请求上req.isAuthenticated()
,而不是调用passport.authenticate()
方法passport.user
的数据,但是 req.user
为 undefined
,passport.deserializeUser()
方法没有被调用的情况: express-session
, passport.initialize()
, passport.session()
三个中间件的顺序cookie.secure
设为 false
,否则通过 HTTP 请求时 passport.deserializeUser()
会没有被调用req.logIn()
没有被调用。如果在调用 passport.authenticate(‘local’, custtomCallback)
时使用了自定义的回调函数,需要手动调用 req.logIn()