首页 > 解决方案 > 过期令牌可以返回 401 而不是 403?

问题描述

我希望能够在 JWT 令牌到期时返回 401(我相信这是正确的响应?)但无论如何它都会返回 403

这是我告诉 swagger 工具使用我的不记名令牌验证逻辑的地方:

swaggerTools.initializeMiddleware(swaggerObject, (middleware) => {
            // Interpret Swagger resources and attach metadata to request - must be first in swagger-tools middleware chain
            app.use(middleware.swaggerMetadata());

            //enable cors
            app.use(
              cors({
                methods: ["GET", "POST", "PATCH", "DELETE"],
                origin: "*",
                preflightContinue: false,
                optionsSuccessStatus: 204,
              })
            );

            //verify bearer token for protected apis
            app.use(
              middleware.swaggerSecurity({
                Bearer: (req, authOrSecDef, token, callback) =>
                  //if this is a protected endpoint then token is verified to allow or deny access
                  securityService.verifyToken(
                    req,
                    authOrSecDef,
                    token,
                    callback
                  ),
              })
            );

这是我的 verifyToken 函数..

verifyToken: (req, authOrSecDef, token, callback) => {
          const sendError = (error) => {
            if (error) {
              if (error.name === "TokenExpiredError") {
                return new Problem(401, error.message);
              }
            } else {
              return new Problem(403);
            }
          };

          if (token && token.toLowerCase().indexOf("bearer ") === 0) {
            var tokenString = token.split(" ")[1];

            let completeDecodedToken = jwt.decode(tokenString, { complete: true });

            if (!completeDecodedToken) {
              return callback(sendError());
            }

            //use header.kid to find correct cognito jwk to use
            let jwk = jwks.keys.find(
              (jwk) => jwk.kid == completeDecodedToken.header.kid
            );

            if (!jwk) {
              //must have passed in a token obtained from somewhere else
              return callback(sendError());
            }
            const pem = jwkToPem(jwk);

            jwt.verify(
              tokenString,
              pem,
              { algorithms: ["RS256"] },
              (verificationError, decodedToken) => {
                if (verificationError === null) {
                  // check if the issuer matches
                  var issuerMatch =
                    decodedToken.iss ===
                    `https://cognito-idp.${process.env.AWS_REGION}.amazonaws.com/${process.env.COGNITO_USER_POOL_ID}`;

                  if (issuerMatch) {
                    //add the token to the request so that we
                    //can access it downstream in endpoint if we need
                    req.auth = decodedToken;
                    req.tokenString = tokenString;
                    //if there is no error, just return null in the callback
                    return callback(null);
                  } else {
                    console.error("Issuer did not match");
                    //return the error in the callback if there is one
                    return callback(sendError());
                  }
                } else {
                  //return the error in the callback if the JWT was not verified
                  return callback(sendError(verificationError));
                }
              }
            );
          } else {
            return callback(sendError());
          }
        },

但实际上,当我查看 swagger-tools 源(swagger-security.js)时,我只看到 403 .. 有什么建议吗?

标签: swagger-tools

解决方案


您总是看到 403,因为那是 else 部分并且您的错误对象为空,如果您能够调试,那么您可以控制台记录错误

此外,您的假设是错误是从下面的行返回的,这很可能是错误的,因为错误为空。

//return the error in the callback if the JWT was not verified
              return callback(sendError(verificationError));

在我看来,错误是从

else {
        return callback(sendError());
      }

如果是这种情况,那么您可以从所需的位置发送您的自定义“UnauthorizedError”对象。


推荐阅读