Здравствуйте, я сделал следующее для моей аутентификации и ссылки sh jwt:
моей сущности
export class User extends BaseEntity {
@Field(() => Int)
@PrimaryGeneratedColumn()
id: number;
@Field()
@Column("text")
login: string;
@Column("text")
password: string;
@Column("int", { default: 0 })
tokenVersion: number;
}
Сделайте refre sh и токен авторизации
export const createAccessToken = (user: User) => {
return sign({ userId: user.id }, process.env.ACCESS_TOKEN_SECRET!, {
expiresIn: "15m"
});
};
export const createRefreshToken = (user: User) => {
return sign(
{ userId: user.id, tokenVersion: user.tokenVersion },
process.env.REFRESH_TOKEN_SECRET!,
{
expiresIn: "120m"
}
);
};
Мое промежуточное ПО :
export const isAuth: MiddlewareFn<MyContext> = ({ context }, next) => {
const authorization = context.req.headers["authorization"];
if (!authorization) {
throw new Error("not authenticated");
}
try {
const token = authorization.split(" ")[1];
const payload = verify(token, process.env.ACCESS_TOKEN_SECRET!);
context.payload = payload as any;
} catch (err) {
console.log(err);
throw new Error("not authenticated");
}
return next();
};
Как отправить мой токен клиенту с помощью файлов cookie
export const sendRefreshToken = (res: Response, token: string) => {
res.cookie("jid", token, {
httpOnly: true,
path: "/refresh_token"
});
};
Мой маршрут для получения токена refre sh:
app.post("/refresh_token", async (req, res) => {
const token = req.cookies.jid;
if (!token) {
return res.send({ ok: false, accessToken: "" });
}
let payload: any = null;
try {
payload = verify(token, process.env.REFRESH_TOKEN_SECRET!);
} catch (err) {
console.log(err);
return res.send({ ok: false, accessToken: "" });
}
const user = await User.findOne({ id: payload.userId });
if (!user) {
return res.send({ ok: false, accessToken: "" });
}
if (user.tokenVersion !== payload.tokenVersion) {
return res.send({ ok: false, accessToken: "" });
}
sendRefreshToken(res, createRefreshToken(user));
return res.send({ ok: true, accessToken: createAccessToken(user) });
});
Мой распознаватель для входа и отзыва Refre sh Tokens For User
@Mutation(() => Boolean)
async revokeRefreshTokensForUser(@Arg("userId", () => Int) userId: number) {
await getConnection()
.getRepository(User)
.increment({ id: userId }, "tokenVersion", 1);
return true;
}
@Mutation(() => LoginResponse)
async login(
@Arg("login") login: string,
@Arg("password") password: string,
@Ctx() { res }: MyContext
): Promise<LoginResponse> {
const user = await User.findOne({ where: { login } });
if (!user) {
throw new Error("could not find user");
}
const valid = await compare(password, user.password);
if (!valid) {
throw new Error("bad password");
}
// login successful
sendRefreshToken(res, createRefreshToken(user));
return {
accessToken: createAccessToken(user),
user
};
}
Здравствуйте, я хотел бы знать, как я мог бы вместо этого использовать поле в своей пользовательской таблице, чтобы создать черный список для jwt, я не знаю, могу ли я улучшить код, я знаю, что отправка через cookie-файлы представляет собой риск из xss и csrf, я не знаю, как использовать библиотеку csurf, чтобы избежать этого:
// app.use(require("csurf")({ cookie: true }));
// app.use(csrf());