TypeGraphQL -ユーザー認証 Part2-

TypeGraphQLの認証

Node.jsのExpressなどではユーザーの認証状態によってアクセスできる機能のなどを制限したいのでミドルウェアがよく用いられます。しかしながらGraphQLのresolverはミドルウェアを持たず、開発者は自らcontextのデータをそれぞれのresolver関数に書く必要があります。

TypeGraphQLでは開発を効率的にする認証機能をいくつかもっています。ここではauthCheckerを使います。authCheckerはschema定義と同じところで定義します。


// src/index.ts

const schema = await buildSchema({
  resolvers: [RegisterResolver, LoginResolver, MeResolver],
   authChecker: ({ context: { req } } ) => {
    if(req.session.userId){
        return true 
        }
       return false
      }
  });
                    

user/Register.tsに残してあるRegisterResolverの@QueryのhelloWorld関数に


  // user/Register.ts

  @Authorized()
  @Query(() => String)
  async helloWorld() {
    return "Hello World!";
  }
                    

@Authorized()を先頭につけることでQueryやMutationでauthCheckerをパスしたユーザーのみがアクセスできるという関数にできます。前回ログイン機能を実装時にログインずみでと思うので Playgroundで確かめる前にLogout機能をたしましょう。

Logout Resolver

最後にLogout機能を追加してユーザー認証は終了します。これまでと同様にsrc下にuser/Logout.tsを作成します。


 // src/user/Logout.ts

 import { Ctx, Mutation, Resolver } from "type-graphql";
 import { MyContext } from '../MyContext'
 
 @Resolver()
 export class LogoutResolver{
     @Mutation(() => Boolean)
     async logout(
         @Ctx() context: MyContext
     ): Promise<Boolean>{
         return new Promise(
             (res, rej) => 
             context.req.session!.destroy((err: Error ) => {
             if(err){
                 console.log(err)
                 return rej(false)
             }
             context.res.clearCookie('typeorm')
             return res(true)
         })
         )
     }
 }
                    

context.req.session.destroyでセッションを消すことができます。セッションを消去後に結果を返すようにしたいのでres(resolve)rej(reject)の関数を引数に持つnew Promiseを返すようにします。 セッション消去に成功した場合trueを失敗した場合はfalseを返すようにします。またセットしたcookieを消去したいのでcontext.res.clearCookie('セットしたcookieのname')を使います。contextからreqだけでなくresもアクセスできるようにsrc/MyContext.tsを定義しなおします。


 // src/MyContext.ts

  import { Request, Response } from 'express'

   export interface MyContext {
       req: Request,
       res: Response
   }
                    

ログアウトに成功しましたら、先ほど実装した@Autherized()を試したいのでhelloWorld Queryを実行してみましょう。ログアウトしているため以下のようにエラーが出るはずです。

もう一度ログインし直して実行してください。成功して”Hello World!”がかえってくるはずです。

これでユーザー認証に関する実装は以上になります。実際に本格的なアプリケーションのAPIを作るとなるとメール認証やパスワード再設定などの機能も必要になると思います。こことは別にまた改めて解説したいと思います。興味ある方は是非!
ここまでのGithubコードはこちらから