Skip to content

Latest commit

 

History

History
102 lines (76 loc) · 2.63 KB

README.md

File metadata and controls

102 lines (76 loc) · 2.63 KB

type-graphql-csrf-middleware

CI Status npm version types included

TypeGraphQL middleware for handling csrf tokens with an express server and express-session.

Required Peer Dependencies:

  • express
  • express-session
  • crsf
  • cookie-parser
  • graphql
  • type-graphql

Installation

npm install type-graphql-csrf-middleware

yarn add type-graphql-csrf-middleware
import { ValidAntiForgeryToken } from "type-graphql-csrf-middleware";

Getting Started

Your express server will need to add a csrf token as a cookie and a csrf secret to the session. Below is an example express route middleware to add the tokens.

const addCsrf = (req: Request, res: Response, next: NextFunction) => {
    const tokens = new Tokens();
    const secret = tokens.secretSync();
    const token = tokens.create(secret);

    res.cookie("csrfToken", token);
    req.session.csrfSecret = secret;

    next();
};

You will also need to add the express Request object to the GraphQL context so that it can be used by the middleware. Here is an example using Apollo Server Express.

const app = express();

const server = new ApolloServer({
    schema,
    context: ({ req, res }) => ({ req, res })
});

server.applyMiddleware({
    app,
    path: "/api"
});

Resolver Middleware Use

The type-graphql middleware needs a cookie key and a session key that are used in your express route middleware function like the previous example in order to verify the token.

import { ValidAntiForgeryToken } from "type-graphql-csrf-middleware";

@Resolver(User)
export class UserResolver {
    @Query(() => User)
    @UseMiddleware(ValidAntiForgeryToken({ cookieKey: "csrfToken", secretKey: "csrfSecret" }))
    async me(@Ctx() ctx: MyContext): Promise<User | undefined> {
        {...}
    }
}

The middleware can also be reusable between resolver functions.

import { ValidAntiForgeryToken } from "type-graphql-csrf-middleware";

const Authorized = ValidAntiForgeryToken({
    cookieKey: "csrfToken",
    secretKey: "csrfSecret",
    message: "Access Denied!"
});

{...}

@Resolver(User)
export class UserResolver {
    @Query(() => User)
    @UseMiddleware(Authorized)
    async me(@Ctx() ctx: MyContext): Promise<User | undefined> {
        {...}
    }
}