护照-jwt 总是返回 401 未授权
Posted
技术标签:
【中文标题】护照-jwt 总是返回 401 未授权【英文标题】:passport-jwt always return 401 unauthorized 【发布时间】:2019-08-29 13:33:36 【问题描述】:我正在尝试使用 passport-jwt 身份验证策略对 nodejs api 进行身份验证,但它总是抛出 401 未经授权的错误。我尝试了各种实现,但 passport.authenticate 功能似乎不起作用。
使用以下护照版本: "护照": "^0.4.0", "passport-jwt": "^4.0.0",
请看我下面的代码:
尝试了以下选项:
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken()
jwtFromRequest: ExtractJwt.fromHeader('authorization')
jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme('Bearer')
jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme('jwt')
但不工作。
尝试查看passport-jwt 401 Unauthorized 和其他链接以供参考。
app.js 文件:
const express = require('express');
const bodyParser = require('body-parser');
const passport = require('passport');
const cors = require('cors');
const app = express();
const login = require('./routes/login');
app.use(cors());
app.use(bodyParser.urlencoded( extended: false ));
app.use(bodyParser.json());
// app.use(passport.initialize());
app.use('/', login);
app.listen(8000, () => console.log('Server running on http://localhost:8000/'));
路由文件夹中的login.js文件:
const express = require('express');
const router = express.Router();
const passport = require('passport');
const passportref = require('./../controllers/passport');
const loginController = require('./../controllers/loginController');
router.post('/putemailregistration',loginController.putEmailregistration);
router.get('/login', passportref.authenticate,loginController.verifyLogin);
module.exports = router;
Passport.js 文件:
const passport = require('passport');
const JWTStrategy = require("passport-jwt").Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const models = require('./../models');
const opts =
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: 'incredible',
passport.use(new JWTStrategy(opts,async (payload, done) =>
try
console.log(`inside jwt strategy func`);
const user = models.Userabout.findById(
where: email: [Op.eq]: payload.email ,
attributes: ['id', 'email', 'password'],
);
console.log(`value of user: $user`);
if (typeof user !== 'undefined' && user !== null)
return done(null, user);
else
return done(null, false);
catch (err)
done(err, false);
));
module.exports =
initialize: () => passport.initialize(),
authenticate: passport.authenticate("jwt", session: false ),
;
loginController.js 文件:
const Op = require('sequelize');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const models = require('./../models');
const saltRounds = 10;
module.exports.putEmailregistration = async (req, res) =>
try
console.log(`inside put email registration`);
if (req.body.email === null || req.body.password === null)
res.sendStatus(400).json('no data');
else
const emailregister = await models.Userdata.create(
email: req.body.email,
password: bcrypt.hashSync(req.body.password,
bcrypt.genSaltSync(saltRounds)),
);
const tokenid = jwt.sign(
id: emailregister.id,
email: emailregister.email,
, process.env.JWT_SECRETKEY,
expiresIn: 3600 );
res.json( success: true, token: 'bearer ' + tokenid );
catch (err)
console.log(`error at put email registration: $err`);
module.exports.verifyLogin = (req, res) =>
console.log(`i managed to get here`);
// console.log(`user: $req.user`);
// res.send(req.user.email);
【问题讨论】:
已经发布请检查***.com/questions/45897044/… 是的@Vijay,我试过了。我在我发布的问题中也引用了该链接。但它似乎不起作用。 【参考方案1】:就我而言,我使用的是环境变量中的expiresIn
值。环境变量值将是String
类型,如果我们将字符串值传递给expiresIn
,它将以毫秒为单位。因此,3600 的值被转换为 3 秒,当我将令牌从登录响应复制到 auth 标头时,它已经过期了。
https://www.npmjs.com/package/jsonwebtoken#usage
【讨论】:
【参考方案2】:要解决这个问题,您可以在中间件中管理它
function authorized(request, response, next)
passport.authenticate('jwt', session: false, , async (error, token) =>
if (error || !token)
response.status(401).json( message: 'Unauthorized Message' );
try
console.log('token',token)
const user = await User.findOne(
_id: token._id
);
request.user = user;
catch (error)
next(error);
next();
)(request, response, next);
router.get(
'/',
authorized,
trimRequest.all,
user.getItems
)
【讨论】:
【参考方案3】:使用
passport.use('jwt',new JWTStrategy(opts,verify_callback())
in passport.js
【讨论】:
【参考方案4】:经过大量调试,我终于解决了这个问题。希望这可能对某人有所帮助
-
我错误地指出了 passport.js 文件中的错误模型。是 Userdata 而不是 Userabout。
在 loginController.js 文件中我更改如下:
常量负载 = id: emailregister.id
const token = jwt.sign(payload, jwtOptions.secretOrKey);
使用以下选项效果很好。
jwtOptions.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme('Bearer');
【讨论】:
以上是关于护照-jwt 总是返回 401 未授权的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 护照 oauth 路线总是返回 401 未经授权
每当我发送包含 Bearer 令牌的请求时,ASP.Net Core API 总是返回 401 未授权