在Node js中使用Azure函数为CRUD编写JWT授权

7qhs6swi  于 2023-06-22  发布在  Node.js
关注(0)|答案(1)|浏览(79)

当用户成功登录时,它将提供JWT令牌。
httptrigger 1文件夹,index.js代码如下:

const response = require("../traits/api_response");
const Database = require("../model/database");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const config = require("../config/config");

module.exports = async function (context, req) {
  context.log("JavaScript HTTP trigger function processed a request.");

  var raw_data = req.body;

  try {
    // await need to send the data here
    const database = new Database(config);
    const email = raw_data.email;
    const password = raw_data.password;

    const user = await database.findEmail(email);
    //console.log(user);
    if (user && (await bcrypt.compare(password, user.password))) {
      const token = jwt.sign(
        { user: user.userId, email },
        `${process.env.TOKEN_KEY}`,
        {
          expiresIn: "12h",
        }
      );
      console.log("It find user email successfully.");
      context.res = {
        status: 200,
        headers: {
          "Content-Type": "application/json",
        },
        body: response.success(
          token,
          `Successfully going into the MS Sql server to get login information`
        ),
      };
    }
    database.disconnect();
  } catch (err) {
    console.log(err);
    context.res = {
      status: 500,
      headers: {
        "Content-Type": "application/json",
      },
      body: response.error(array_data, `${err.message}`),
    };
  }
};

httptrigger 1文件夹function.json

{
  "bindings": [
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": ["post"],
      "route": "login"
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    }
  ]
}

我用azure函数创建了另一个端点,它必须接受身份验证才能从系统中获取数据。换句话说,我创建了另一个get端点,它需要使用login JWT进行授权。
我创建了middleware文件夹和middleware/auth.js。代码如下:

const jwt = require("jsonwebtoken");

const verifytoken = (req, res, next) => {
  const token = req.headers["x-auth-token"];

  if (!token) {
    res.status(403).send("A token is required for authentication");
  }
  try {
    const user = jwt.verify(token, process.env.TOKEN_KEY);
    req.user = user;
    console.log("middleware is working");
    return next();
  } catch (err) {
    res.status(401).send("Invalid Token");
  }
};

module.exports = verifytoken;

另一个端点httptrigger 2文件夹function.json

{
  "bindings": [
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": ["get"],
      "route": "getuser/{userId}"
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    }
  ]
}

在httptrigger 2文件夹中,index.js。

const response = require("../traits/api_response");
const Database = require("../model/database");
const config = require("../config/config");
const verifytoken = require("../middleware/auth");

module.exports = async function (context, req) {
  context.log("JavaScript HTTP trigger function processed a request.");
  try {
    const { userId } = context.bindingData;
    console.log("Getting from the localhostlink: ", userId);
    if (!userId) {
      context.res = {
        status: 400,
        headers: {
          "Content-Type": "application/json",
        },
        body: response.error([], `User ID muct put!`),
      };
      return;
    }

    const database = new Database(config);
    if (verifytoken()) {
      const user = await database.findID(userId);

      context.res = {
        status: 200,
        headers: {
          "Content-Type": "application/json",
        },
        body: response.success(
          user,
          `Successfully going into the MS Sql server to get login information.`
        ),
      };
      database.disconnect();
    }
  } catch (err) {
    context.res = {
      status: 200,
      headers: {
        "Content-Type": "application/json",
      },
      body: `${err.message}`,
    };
  }
};

Postman 的输出如下;

Cannot read properties of undefined (reading 'headers')

解释>>>我上面的代码没有在JWT授权下运行。当用户成功登录时,它确实提供了JWT令牌,但它没有使用JWT保护另一个端点,即“getuser/{userId}”函数。我确实做了中间件来验证令牌,它调用了端点函数,但是,它没有工作。请问你能帮我怎么写吗?

qlvxas9a

qlvxas9a1#

const  jwt = require("jsonwebtoken");
module.exports = async  function  (context,  req)  {
try  {
const  decodedToken = jwt.decode(req.headers.authorization.split(" ")[1]);
with a greeting message and default 200 status code
status code
context.res =
decodedToken.scp.split(" ").indexOf("Greeting.Read") > -1
? {
body:  "Hello, world. You were able to access this because you provided a valid access token with the Greeting.Read scope as a claim.",
}
: {  body:  "Missing required scope.",  status:  403  };

}  catch (error) {
context.res = {  body:  "Invalid token.",  status:  403  };
}
};

注:

在撰写本文时,Function应用程序身份验证不支持与on-Azure运行时等效的本地开发环境。这仍然可以使用func start本地运行,但是,不会使用Azure的Function应用服务的身份验证功能,并且将忽略所有用于授权的JWT令牌验证(签名,iss,exp,AUD)。
另一种方法是添加用户并访问它。

const  accessToken = jwt.sign(

{  "username":  foundUser.username  },

process.env.ACCESS_TOKEN_SECRET,

{  expiresIn:  '30s'  }

);

const  refreshToken = jwt.sign(

{  "username":  foundUser.username  },

process.env.REFRESH_TOKEN_SECRET,

{  expiresIn:  '1d'  }

);

const  otherUsers = usersDB.users.filter(person  =>  person.username !== foundUser.username);

const  currentUser = { ...foundUser,  refreshToken  };

usersDB.setUsers([...otherUsers,  currentUser]);

await  fsPromises.writeFile(

path.join(__dirname,  '..',  'model',  'users.json'),

JSON.stringify(usersDB.users)

);

res.json({  'success':  `User ${user} is logged in!`  });

输出:

引用自git

相关问题