Closed fengmk2 closed 7 years ago
以 oauth 登录作为标准的示例实现。
哈哈,这个也挺老了
@popomore 我看它是最完善的。
淘宝登录也有需求 egg-taobao-login
egg-dingtalk-login 🤔
认领 egg-weibo-login,接一个先试试
看来还是得封装 egg-passport-xxx
,因为需要统一约定处理 afterAuth,并且将 {token, tokenSecret, profile}
转换为统一字段约定的 user,至少要包含哪些统一命名的字段。
这些 passport 的 adapter 跟插件有些区别吧,需允许多个共存,不一样的 eggPlugin.name?
感觉直接传 Strategy 实例比较好,不同的 Strategy 参数不一样,也可能会有两个。
exports.passport = {
strategy: [
new TwitterStrategy({
consumerKey: TWITTER_CONSUMER_KEY,
consumerSecret: TWITTER_CONSUMER_SECRET,
callbackURL: "http://127.0.0.1:3000/auth/twitter/callback"
},
function(token, tokenSecret, profile, cb) {
User.findOrCreate({ twitterId: profile.id }, function (err, user) {
return cb(err, user);
});
})
]
};
把 passport 的 callback API 都要改成 promise 的
auto0 还有一个 params 参数: accessToken, refreshToken, extraParams, profile
https://github.com/auth0/passport-auth0#configuration
@popomore 还是改成 passport-xx 模式了,每个插件都需要按照统一 user 数据格式实现 verify 方法,生成一个 user,再由应用自行实现总的 verify 来做最终用户校验。没办法每个插件能使用到数据库实现 verify 的。
但这个就不算 passport 了,用什么来存储用户信息和 passport 没关系。内部可以直接在 Strategy 里面封装获取用户信息。
内部可以直接在 Strategy 里面封装获取用户信息。
@popomore 对啊,内部应用代码就不需要实现 verify 了
app.passport.verify 的 hook 就是替换 strategy 里的 verify callback 么?
@popomore 不完全是,strategy verify callback 有 passport-xxx 插件实现。而 app.passport.verify 是我们封装过的,给应用使用的。这样一个应用同时接入多种 strategy,都可以通过同一个 app.passport.verify 实现最终核实过程。
恩,功能是一样的,只是数据格式是否统一。他的 passport-stragery
基类其实什么都没做,约定比较松散。
只是我们约定插件来实现 verify callback
对于每次都去缓存读取用户信息的 user,需要默认关闭 passport-session 策略。
const auth = app.passport.authenticate('alipaysession', {
session: false,
successReturnToOrRedirect: false,
successRedirect: false,
});
// 将 auth 加入全局中间件,让每个请求都过 alipaysession
app.use(auth);
但是要追求高性能的话,alipaysession 应该直接走普通中间件,不走 passport 这台,因为它是每次请求都去缓存读取数据的。
@shaoshuai0102 https://github.com/eggjs/egg-passport-weibo 基本不需要做,我需要想想怎么 mock 方便写单元测试才是王道。
这个是不是还缺篇文档?
恩,要加一下
passport-local 该怎么做?有参考么?
@yandongxu 我也不会这个 passport-local
@yandongxu @dangyanglim https://github.com/leiyanggz/egg-passport-local
@leiyanggz 这个没写测试?
为什么在egg-passport中, 重写passport的方法时, 要把callback去掉, 是暂时不支持还是不打算支持呀?
@jackhutu 我们最佳实践是 generator function 和 async function,所有的代码应该看不到 callback。
async login() {
const { body } = this.ctx.request;
const { email: _email, password: _password } = body;
const rule = {
email: {
type: 'email',
},
password: {
type: 'password',
},
};
try {
this.ctx.validate(rule);
} catch (err) {
console.log(err);
this.ctx.redirect('/user');
return;
}
const user = await this.app.mysql.get('users', { email: _email });
const dbpw = user.password;
const fmpw = crypto.MD5(_password).toString();
if (user && dbpw === fmpw) {
console.log('登陆成功');
this.app.passport.serializeUser(async (ctx, user) => {
console.log('000000', user);
// 保存用户信息到session
});
this.ctx.redirect('/user');
} else {
console.log('登陆失败');
}
}
@fengmk2 本地鉴权怎么用啊?感觉调用this.app.passport.serializeUser并没有成功啊 session里没有东西 this.app.passport.deserializeUser方法也没用 教程省略了太多 对小白太难了 求指点
app.passport.serializeUser
是写在 app.js 的
RFC: passport
由于业界的 passport 已经足够简单,egg 做起来就是配置。对应应用开发者,更加是配置,基本无需编写代码就能实现。
一个应用的 authenticate 通用过程
app.passport.verify
hook,这样应用层就能做最终的核实,例如做新用户注册,老用户绑定校验等等,这里也是用户数据持久化的地方。app.passport.deserializeUser
和app.passport.serializeUser
来还原 session。说明
统一 user 字段约定
ctx.user
是一个 getter,真实数据来自于ctx.state.user
。每个 passport-xxx 插件都需要按照约定封装一个 user。
user.provider
: 用户信息来自那种登录策略,如 twitter, weibo, facebook,这样就能通过此字段读取user.profile
信息了。一般都是自动填充user.id
: 用户 id,字符串user.name
: 用户名user.displayName
: 昵称user.token
: oauth1 的话必须提供user.tokenSecret
: oauth1 的话必须提供user.accessToken
: oauth2 的话必须提供user.refreshToken
: oauth2 的话必须提供user.profile
: profile 的其他字段,每个平台提供的都不太一样,需要各种区别passport 配置
应用需要关注的3个用户数据处理 hooks