authentication
22672 ワード
import bcrypt from "bcrypt";
import jwt from "jsonwebtoken";
import client from "../../client";
export default {
Mutation: {
editProfile: async (
_,
{ firstName, lastName, username, email, password: newPassword, token }
) => {
const { id } = await jwt.verify(token, process.env.SECRET_KEY);
let uglyPassword;
if (newPassword) {
uglyPassword = await bcrypt.hash(newPassword, 10);
}
const updatedUser = await client.user.update({
where: {
id,
},
data: {
firstName,
lastName,
username,
email,
password: uglyPassword,
},
});
if (updatedUser.id) {
return {
ok: true,
};
} else {
return {
ok: false,
error: "Could not update profile.",
};
}
},
},
};
しかし、すべてのMutationにtokenを提供するのはあまりにも効率的ではありません.また,verify
を用いてtokenを導入するのも面倒な作業である.ソリューション
すべてのtokenをMutationからインポートし、ヘッダとして受け取ったtokenにアクセスする必要があります.したがって、HTTP Headersを使用し、HTTP Headersはrequest、responseの一部であり、任意の値を入れることができます.
だからHTTP Headersにtokenを入れる
export default {
Mutation: {
editProfile: async (
_,
{ firstName, lastName, username, email, password: newPassword },
{ token }
) => {
const { id } = await jwt.verify(token, process.env.SECRET_KEY);
let uglyPassword;
if (newPassword) {
uglyPassword = await bcrypt.hash(newPassword, 10);
}
const updatedUser = await client.user.update({
where: {
id,
},
data: {
firstName,
lastName,
username,
email,
password: uglyPassword,
},
});
if (updatedUser.id) {
return {
ok: true,
};
} else {
return {
ok: false,
error: "Could not update profile.",
};
}
},
},
};
editProfile resolver
には4つの論点があり、そのうちの1つはcontext
である.context
はobject
であり、すべての解析器にアクセス可能な情報を入れることができる.したがってcontextにトークンを追加すると、そのトークンはすべての解析器からアクセスできます.
しかし、もう一つの問題はcontextが関数になる可能性があり、トークン自体を入れると危険になる可能性があるということです.
サーバ側がcontextからのreqをチェックするとgraphqlのタグを表示できます.
context: ({ req }) => {
return {
token: req.headers.token,
};
},
このように使うことができますが、これは最善の方法ではありません.editProfile.resolvers.jsで
const { id } = await jwt.verify(token, process.env.SECRET_KEY);
上記のコードがアップロードやコメントなどすべての場所で作成されているとすれば、効率は非常に低い.でもサーバーにUserを送ったらどうですか?
//users.utils.js
export const getUser = async (token) => {
try {
if (!token) {
return null;
}
const { id } = await jwt.verify(token, process.env.SECRET_KEY);
const user = await client.user.findUnique({ where: { id } });
if (user) {
return user;
} else {
return null;
}
} catch {
return null;
}
};
//server.js
const server = new ApolloServer({
schema,
context: async ({ req }) => {
return {
loggedInUser: await getUser(req.headers.token),
};
},
});
//editProfile.resolvers.js
export default {
Mutation: {
editProfile: async (
_,
{ firstName, lastName, username, email, password: newPassword },
{ loggedInUser } //token 대신에 loggedInUser 보냄
) => {
let uglyPassword = null;
if (newPassword) {
uglyPassword = await bcrypt.hash(newPassword, 10);
}
const updatedUser = await client.user.update({
where: {
id: loggedInUser.id,
},
data: {
firstName,
lastName,
username,
email,
...(uglyPassword && { password: uglyPassword }),
},
});
if (updatedUser.id) {
return {
ok: true,
};
} else {
return {
ok: false,
error: "Could not update profile.",
};
}
},
},
};
Reference
この問題について(authentication), 我々は、より多くの情報をここで見つけました https://velog.io/@gktmd652/authenticationテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol