英文:
Write JWT Authorization for CRUD using Azure function in Node js
问题
以下是翻译好的部分:
当用户成功登录时,它提供JWT令牌。
httptrigger1文件夹,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触发函数处理了一个请求。");
var raw_data = req.body;
try {
// 需要在此处发送数据
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("成功找到用户电子邮件。");
context.res = {
status: 200,
headers: {
"Content-Type": "application/json",
},
body: response.success(
token,
"成功进入MS SQL服务器以获取登录信息"
),
};
}
database.disconnect();
} catch (err) {
console.log(err);
context.res = {
status: 500,
headers: {
"Content-Type": "application/json",
},
body: response.error(array_data, `${err.message}`),
};
}
};
httptrigger1文件夹,function.json
{
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": ["post"],
"route": "login"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
我已经提供了代码的翻译部分。如果需要更多帮助或有其他问题,请随时提出。
英文:
When the user logs in successfully, it provides the JWT token.
The httptrigger1 folder, index.js The code is as below:
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}`),
};
}
};
That httptrigger1 folder, function.json
{
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": ["post"],
"route": "login"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
I create another endpoint with azure function which will have to accept the authentication in order to fetch the data from the system. In other words, I create another get endpoint which needs to be authorization with login JWT.
I created middleware folder and middleware/auth.js. The code is as below:
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;
Another endpoint httptrigger2 folder, function.json
{
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": ["get"],
"route": "getuser/{userId}"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
In httptrigger2 folder, 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}`,
};
}
};
the output in postman is under as below;
Cannot read properties of undefined (reading 'headers')
Explanation >>>
My above code did not run with JWT authorization. It did provide the JWT token when user login successfully, but it did not protect with JWT for the other endpoint which is 'getuser/{userId}' function. I did make the middle ware to verify token and it called in endpoint function, however, it did not work.
Could you please help me how can i write this?
答案1
得分: 1
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 };
}
};
英文:
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 };
}
};
Note:
Function app authentication does not, as of the time of this writing, support a local development environment that is equivalent to the on-Azure runtime. This can still be run locally using func start, however, Azure's Function app service's authentication features won't be used, and all JWT token validation for authorization (signature, iss, exp, AUD) will be disregarded.From this MSDOC.
Another method is adding a user and accessing it.
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!` });
Output:
Referred from this git.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论