成功登录后我收到了jwt令牌,现在访问受限制的api我正在发送授权标题,但我总是得到
401未经授权
我已经提到了这里提出的Authenticating node API with passport-jwt问题,但没有帮助我,
这是我要求从resticted api
访问数据的函数check() {
console.log(this.token);
var headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append("Authorization", "Bearer" + this.token);
let url = this.authenticationEndPoint + 'random';
this.checkauth(url, headers).subscribe(
data => {
console.log(data);
},
error => {
console.log("error");
}
);
}
checkauth(url:string, header:any): Observable<any> {
return this.http.get(url, header)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res;
return body || {};
}
在nodeJs的服务器上,这里是发送jwt令牌的登录代码:
app.post('/login_mobile', function(req, res) {
if(!(req.body.email && req.body.passpord)) {
user.findOne({'local.email' : req.body.email}, function(err, user) {
if (err) { return done(err);}
if (!user) {
return res.json(200, "email is wrong");
}
if(!user.validPassword(req.body.password)) {
return res.json(200, "wrong password");
}
var token = jwt.encode(user, configAuth.secret);
return res.json(200, { user: user, jwtToken: token });
});
}
else {
res.send("no credentials provided");
}
});
响应受限api请求的代码
app.get('/random', passport.authenticate('jwt', { session: false }),
function(req, res) {
res.send("success");
});
这是我用来验证用户身份的护照策略,但奇怪的是它甚至不打印这里仍然发送401状态。
var opts = {};
opts.secretOrKey = configAuth.secret;
opts.jwtFromRequest = ExtractJwt.fromAuthHeader();
passport.use(new JwtStrategy(opts, function(jwt_payload, done){
console.log("here");
console.log(jwt_payload);
User.findOne({_id: jwt_payload._id}, function(err, found_user) {
if (err) {
return done(err, false);
}
if(found_user !== null) {
res.send("finally");
}
else {
res.send("authentication failed");
}
return found_user ? done(null, found_user) : done(null, false);
})
}));
如果有人可以指出我的错误。
答案 0 :(得分:3)
我修复了一个类似的问题:
jwtFromRequest: ExtractJwt.fromAuthHeader(),
使用:
jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme('Bearer'),
答案 1 :(得分:2)
我正在头痛,经过几个小时的环顾四周解决了这个问题。
答案类似于这里的答案:
Authenticating node API with passport-jwt
在这里:
passport local strategy not getting called
使调试变得如此困难的原因是,如果没有获得预期信息,策略甚至不会运行。在后者中,LocalStrategy
验证回调未被启动,因为它没有收到用户名和密码。
在我的情况下,可能与您的相同,但是标题中没有以正确的格式提供JWT令牌。这是因为,在成功登录后,我返回了一个这样的令牌:
res.status(200).json({
token: `JWT${generateToken(userInfo)}`,
user: userInfo,
});
当我应该这样做时:
res.status(200).json({
token: `JWT ${generateToken(userInfo)}`,
user: userInfo,
});
查看JWT之后的空间。所以,我的jwtStrategy函数接收到JWTx759ghv...
之类的东西作为auth令牌,当它期待JWT x759ghv...
时
如果Passport对此发出警告,那将会很方便!
这是我的完整设置,以防有任何帮助:
// passportService.js
const passport = require('passport');
const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const LocalStrategy = require('passport-local');
const User = require('../models/User');
const config = require('../config');
/**
* Local Login Strategy
*/
const localOptions = {
usernameField: 'email',
};
const localLogin = new LocalStrategy(localOptions, (email, password, done) => {
console.log('Using Local strategy');
console.log(email, password);
User.findOne({ email }, (err, user) => {
if (err) { return done(err); }
if (!user) { return done(null, false, { message: 'Your login details could not be verified. Please try again.' }); }
user.comparePassword(password, (passwordErr, isMatch) => {
if (passwordErr) { return done(passwordErr); }
if (!isMatch) { return done(null, false, { message: 'Your login details could not be verified. Please try again.' }); }
return done(null, user);
});
return false;
});
});
/**
* JWT Strategy
*/
const jwtOptions = {
jwtFromRequest: ExtractJwt.fromAuthHeader(),
secretOrKey: config.auth.passport.key,
};
console.log(jwtOptions);
const jwtLogin = new JwtStrategy(jwtOptions, (payload, done) => {
User.findById(payload._id, (err, user) => {
if (err) {
return done(err, false);
}
if (user) {
done(null, user);
} else {
done(null, false);
}
});
});
passport.use(localLogin);
passport.use(jwtLogin);
module.exports = {
initialize: () => passport.initialize(),
authenticateJWT: passport.authenticate('jwt', { session: false }),
authenticateCredentials: passport.authenticate('local', { session: false }),
};
然后,在我的路线中使用:
// ... after of the other Express app initialization
const passportService = require('./services/passport');
const AuthenticationController = require('./controllers/Authentication');
const requireToken = passportService.authenticateJWT;
const requireCredentials = passportService.authenticateCredentials;
app.use(passportService.initialize());
authRoutes.post('/register', AuthenticationController.register);
apiRoutes.get('/protected', requireToken, AuthenticationController.login);
authRoutes.post('/login', requireCredentials, AuthenticationController.login);
如果您仍然遇到问题,请在调用策略之前尝试运行一小块中间件,以确保您发送的标头格式正确:
apiRoutes.get('/protected', (req, res) => {
console.log(req.headers);
}, requireToken, AuthenticationController.login);