Egg,我是用来做RESTful,api服务器,所以返回成功或失败跳转,意义不大
app.passport.verify(async (ctx, user) => {
ctx.logger.debug('passport.verify', user)
// 我试过下面的方案,不行
if (true) {
ctx.body = { status: 'success' }
} else {
ctx.body = { status: 'error' }
}
// 下面这样的写法,也不行
const err = new Error('错误了');
err.code = 'error_code';
throw err
// return existUser
return user
})
我是配合 ant design pro用的。登录成功后,跳转页面,也是由ant design pro判断status来处理的。如果status === 'error',我会返回额外信息,由ant design pro页面提示错误,比如密码不正确
i have same problem。
还有一个疑问,这个验证,无论成功或者失败,都是返回302。我可以手工指定返回码吗,比如返回200?
// 鉴权
const localStrategy = app.passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/api/signIn'
});
跳到相应的(api)页面应该可以处理,verify里面只是校验。这种方式虽然可以。但是好像开发思路有点不直观。
对,除了不直观,而且,缺乏有效返回错误信息的途径。只是用来写RESTful,api服务器,前端是react
我设计的流程是,如果验证失败,return null,body={ status: 'error', type: 'password' }。
我前端接收到返回的body,就可以渲染页面,提示密码错误,不需要跳转
http://www.passportjs.org/docs/login/ 可以看看这个,看看有没有解决方案了。
好的,我看看去
@fengmk2 @popomore 大神,求助哈
这里的问题好像在群里讨论过
参考:
谢谢,egg-cnode这个我之前看过了。
刚粗略看了下passport和passport-local的源码,想实现我设想的功能,需要改源码,默认是实现不了的。
改源码简单,维护起来就麻烦了,每次重置库,都需要再次修改库代码
仔细看了下源码,如果直接用passport和passport-local,可以通过callback来实现。但是,egg-passport不支持传递callback
authenticate函数忽略了第四个参数callback,下面代码摘自egg-passport/lib/framework.js
function authenticate(passport, name, options) {
// Don't support authenticate with callback
// function authenticate(req, res, next)
const connectMiddleware = connectFramework.authenticate(passport, name, options);
debug('use authenticate:%s, options: %j', name, options);
@fengmk2 @popomore 大神给点建议哈
其实如果只是账号登陆的话,都没必要用 passport-local,自己做一个 post 就完事了。
Passport 是设计来给第三方登陆用的。
我在[email protected]@passport\lib\middlewaremd5-8e9fd8402a16b5ddb359a7847a3e15b9uthenticate.js手工硬加入下面代码,就可以了。先凑合着用,后面再想办法,第三方登录是需要的,想统一登录,所以想用passport
return function authenticate(req, res, next) {
if (http.IncomingMessage.prototype.logIn
&& http.IncomingMessage.prototype.logIn !== IncomingMessageExt.logIn) {
require('../framework/connect').__monkeypatchNode();
}
> callback = function(err, user, info) {
> if (err) { return next(err) }
>
> if (user.error) {
> return res.end(user.body)
> }
>
> req.logIn(user, function(err) {
> if (err) { return next(err) }
> return res.end(user.body)
> })
> }
// accumulator for failures from each strategy in the chain
var failures = [];
node_modules 一般不要动,npm update 一下就没了。
没啥必要统一
明白了,那我不用了,还是直接单独写个post吧,谢谢
其实可以给 app.passport.authenticate 包成一个 promise,通过中间件的方式在 route 中使用,就可以直接返回 json 了。
// middleware/auth.js
'use strict';
module.exports = () => {
return async function(ctx, next) {
const app = ctx.app;
if (app.passport) {
const localStrategy = new Promise(resolve => {
app.passport.authenticate('local', (err, user) => {
if (err) {
resolve({ success: false, message: err });
}
if (!user) {
resolve({ success: false, message: 'current user not exit.' });
}
resolve(user);
})(ctx);
});
ctx.body = await localStrategy.then(res => res);
await next();
}
};
};
@atian25 我觉得对于passport来说,这个密码登录的功能可能没特别的必要。不过保持koa插件功能完整还是很有必要的。不过我看以现在egg把插件功能打散这种方式,可能有些功能实现起来有些麻烦。
@whlsxl 就这个问题来说,我个人觉得是 passport 的问题,毕竟它是 express 风格的插件,来转换为 koa 风格,毕竟 hacky 。 打散这个也不是 egg 本意,而是 Passport 本身就分为那么多 Strategy
我的做法是 自己判断登录 然后
ctx.login(user); 传给passport(用于利用 sessiong 和 登录验证方法ctx.isAuthenticated)
`
async login() {
if(true){
ctx.login(user)
}
}
async currentUser() {
const { ctx } = this;
if (ctx.isAuthenticated()) {
ctx.body= {username:'aaa'};
}else{
ctx.response.status = 401;
}
}
`