GraphQL Typescript Authentication Boilerplate

Поделиться
HTML-код
  • Опубликовано: 28 ноя 2024

Комментарии • 77

  • @eleah2665
    @eleah2665 5 лет назад

    Hi Ben, I woke up with a sore throat this morning. Probably will develop into full blown cold and will take about two weeks to get over. Your video classes are always great.

  • @katielamber0238
    @katielamber0238 5 лет назад +2

    oh, now I understand why you disappeared. Hope you will be well now. Thanks for all you do

  • @juancamiloq1
    @juancamiloq1 5 лет назад +11

    You got code burn man. Please take a strict rest calendar

  • @md.akib5124
    @md.akib5124 5 лет назад +4

    Welcome back Ben. Love you man

  • @DanishAnton
    @DanishAnton 5 лет назад +2

    Great setup! Couple questions:
    1. Do you validate incoming parameters using yup or some other validator? For example, email may not be an actual email.
    2. I throw custom Errors for all errors and allow graphql to manage the error. I have three so far (Authentication, Authorization, Field). The frontend than parses and handles the error. Still not sure if this is best implementation. I haven't yet figured out how to block all other error types for production. How do you handle uncaught errors like from faulty code, db, etc?
    3. If a malicious user somehow does copy the 7 year old cookie and uses it on their end, would you recommend checking ip and/or other specs to further validate cookie? Maybe I'm overthinking it...
    Your voice still sounds a bit rough. Rest well.

    • @bawad
      @bawad  5 лет назад +1

      1. yeah yup
      2. The convention I like to use is throw an error in middleware or if an unexpected error is encountered and return errors if I expect they could happen. Here's how I handle unexpected errors ruclips.net/video/7oLczJD6zZI/видео.html
      3. maybe, depending on the type of application. I feel like in most cases it's overkill and ip can change so it can be hard to get a good fingerprint (though maybe some users don't want you to fingerprint them).
      yeah going to rest it, still feels weird

    • @tafelito
      @tafelito 5 лет назад

      ​@@bawad Why did you add the FieldError in the user response instead of actually throwing an error? Also why yup and not joi

    • @bawad
      @bawad  5 лет назад

      1. preference
      2. tried yup first

  • @liftingisfun2350
    @liftingisfun2350 2 года назад

    Do you have any upgraded guides or tools for generating a graphql apollo typescript api to be used with a typescript react/redux frontend?

  • @theemacsen1518
    @theemacsen1518 5 лет назад +2

    Aye your back man!!!
    Get well soon BruH

  • @bulldog2024
    @bulldog2024 5 лет назад

    Hope you feel better.

    • @bawad
      @bawad  5 лет назад

      thanks

  • @elegiggle7882
    @elegiggle7882 5 лет назад

    Would you consider adding Redis as an optional dependency? like give another parameter --redis for session storage

    • @bawad
      @bawad  5 лет назад

      Do you think it's worth add a flag for it?
      The only difference would be swapping the connect package and installing ioredis

  • @jambaritopervert5732
    @jambaritopervert5732 5 лет назад

    @
    Ben Awad This is my first time working with node.js, apollo-server, graphql. And now I also choose a framework. What to choose and why?

  • @tendies
    @tendies 4 года назад +1

    I really appreciate this, thank you!

  • @АлексейАлексеевич-ш7ю

    Hello Ben! There's a lot of talking about http2 vs graphql, what do you think about that? Will graphql be still usefull?

    • @bawad
      @bawad  5 лет назад +1

      Hard to say until we see http2 become more mainstream, but I still see graphql being useful it has more benefits than just reducing the number of requests to the server

    • @АлексейАлексеевич-ш7ю
      @АлексейАлексеевич-ш7ю 5 лет назад

      @@bawad thanks

  • @ProjektArcadia
    @ProjektArcadia 5 лет назад

    Why do you integrate the errors into the schema and don't throw an Apollo error if the login fails or the email has already been used?
    If you make both properties optional in the response object, theoretically both could be null, would a union be better?

    • @bawad
      @bawad  5 лет назад +1

      1. The convention I like to use is throw an Apollo error in middleware or if an unexpected error is encountered and return errors if I expect they could happen. But it's just a convention, you could throw all your errors if you want
      2. Yeah I think a union describes it better (and is probably the correct choice), but I find objects easier to work with

  • @raphimmo
    @raphimmo 5 лет назад +1

    great video, looking forward for more content on this subject, maybe how to aggregate data while avoiding n+1 problem with graphql ?

    • @herbertpimentel
      @herbertpimentel 5 лет назад

      I just saw he usually uses loaders to avoid it like in this ruclips.net/video/8kZ7W-bI5qQ/видео.html

  • @malvoliosf
    @malvoliosf 4 года назад

    There is an error, or at least an unwise decision in the code, which defines MyContext as { req: Request, res: Response }. That isn't exactly so. For many of the functions to work, "session" must be set on the request, and the type does not reflect that requirement. I think the definition of MyContext should be changed to { req: Request & {session: Session}, res: Response } and the context function in the Apollo middleware should cast or assert that session is set. This change is a sounder alternative to using the "!" everywhere.

    • @bawad
      @bawad  4 года назад

      I like it, thanks for the suggestion

  • @yagizhanavci1119
    @yagizhanavci1119 5 лет назад +2

    Welcome back king!

    • @bawad
      @bawad  5 лет назад

      thanks

  • @yoyo26-34
    @yoyo26-34 5 лет назад

    hi, happy yoyu've done this because I'm facing a major perf issue when comparing the password with bcrypt. It takes almost 10s to decrypt a hashed password of 10 characters using a 16 length salt. Are you facing a similar issue before? The server where app is running is quite powerful, so I guess the issue might be in the decryption algorithm. In your video, comparison is fast. thks

    • @bawad
      @bawad  5 лет назад

      I'm not
      are you using bcryptjs? You could try switching to bcrypt or vice versa
      also lowering your salt will help

  • @navaneeth6157
    @navaneeth6157 5 лет назад +1

    glad your better now :)

  • @MrVijay314
    @MrVijay314 5 лет назад

    Hi Ben. Thanks for amazing video. Would you know why the cookie will not set in browser (the way you showed at end). I can create user, i can log in and see the cookie being returned from the server (localhost:4000) but it doesn't get stored. Hence any authenticated requests like me, and book returns error.

    • @bawad
      @bawad  5 лет назад

      Assuming you set credentials to include in your settings I'm not sure
      Have you tried a different browser?

  • @l3ss1sm0r3
    @l3ss1sm0r3 5 лет назад

    First of all, thank you for sharing this video. One point for improvement for the login resolver could be to also trigger bcrypt hash(password) when no matching user has been found. This way, you make the login requests for existing users quite a bit more indistinguishable from requests without a matching user in the database. Furthermore, I hope that you will be considering CSRF protection in some way?

    • @bawad
      @bawad  5 лет назад

      Good point!
      Add same site to your cookie?

    • @l3ss1sm0r3
      @l3ss1sm0r3 5 лет назад

      @@bawad I think could be a good step in the right direction indeed. You still would have to consider the actual value of the header and it's impact on the browser policy. Setting strict would mean that users coming from somewhere else through a link would not be logged in. Setting it to lax could mean that it might be a good thing to let apollo server to accept POST requests only. Another option to improve the situation could be a referrer check and using CSRF tokens when using sessions. Those things can also be combined. Django in fact does put a sameorigin lax on it's CSRF cookie IIRC. Anyway. Keep up the good work!

  • @herbertpimentel
    @herbertpimentel 5 лет назад +2

    Hey man, thanks for this, this package looks really cool, I am so excited to use it, can you share your thoughts about how to avoid n+1 problems in this model. I really expect you to evolve this... because it is really amazing

    • @herbertpimentel
      @herbertpimentel 5 лет назад +1

      I just saw you usually use loaders to avoid it like in this ruclips.net/video/8kZ7W-bI5qQ/видео.html

  • @user-mt2if1ht8n
    @user-mt2if1ht8n 5 лет назад

    Hi Ben!
    Could you explain please how correctly to use global sass variables in next ts project, thanks!

    • @bawad
      @bawad  5 лет назад

      sorry, I've never used sass before

    • @user-mt2if1ht8n
      @user-mt2if1ht8n 5 лет назад

      @@bawad tell, please, how you pass project colors throughout the project components? What you do if you should change any color after project completed? Thanks!

    • @bawad
      @bawad  5 лет назад +1

      I use styled-components and a theme provider for that

  • @leonesouza8410
    @leonesouza8410 5 лет назад

    Hi Ben, can you show us how do you make Queries with React Hook (experimental mode) and Apollo, thanks.

    • @bawad
      @bawad  5 лет назад

      what trouble are you running into with apollo hooks?

    • @leonesouza8410
      @leonesouza8410 5 лет назад +1

      @@bawad no trouble, just wanna see how you do it, I appreciate the way you code and theres no much videos about it

    • @leonesouza8410
      @leonesouza8410 5 лет назад +1

      "My Thoughts on The Unofficial React Apollo Hooks Library" already helps me thanks again

  • @meridjal
    @meridjal 4 года назад

    This boilerplate is seriously convoluted (after spending a few days trying to connect a frontend)

    • @liftingisfun2350
      @liftingisfun2350 2 года назад

      What was your solution ultimately? I'm trying to make a graphql apollo typescript api for my react frontend and have so many differing guides out there)

  • @senrv4588
    @senrv4588 5 лет назад

    Good afternoon ben awad. And again thank you for your amazing videos, i learnt a lot from you. Just , it seems typeorm transactions are very tricky, sometime i've problem to deal with it with apollo server. Can you, please, if are you are not busy, make a video about that ?.thank you

    • @bawad
      @bawad  5 лет назад

      What problem have you run into?

    • @senrv4588
      @senrv4588 5 лет назад

      @@bawad after queryRunnerCommittransaction, i cant render the result, its seems an infinite loop

    • @bawad
      @bawad  5 лет назад

      did you format it like this
      try {
      // execute some operations on this transaction:
      await queryRunner.manager.save(user1);
      await queryRunner.manager.save(user2);
      await queryRunner.manager.save(photos);
      // commit transaction now:
      await queryRunner.commitTransaction();
      } catch (err) {
      // since we have errors lets rollback changes we made
      await queryRunner.rollbackTransaction();
      } finally {
      // you need to release query runner which is manually created:
      await queryRunner.release();
      }

    • @senrv4588
      @senrv4588 5 лет назад

      i did this createMessage: requireAuth.createResolver(
      async (
      _parent,
      { product_id, text, seller_id, username },
      { user_id: client_id }
      ) => {
      const queryRunner = await getConnection().createQueryRunner();
      await queryRunner.startTransaction();
      try {
      const transactionalEntityManager = queryRunner.manager;
      const repo = getRepository(Conversation);
      const isConversation = await repo.findOne({
      where: { product_id, seller_id, client_id },
      });
      if (isConversation) {
      const message = new Message();
      message.author_id = client_id;
      message.text = text;
      message.conversation_id = isConversation.id;
      await transactionalEntityManager.save(message);
      await queryRunner.commitTransaction();
      emitter.emit('newMessage', {
      destinator_id: seller_id,
      username,
      conversation_id: isConversation.id,
      });
      return {
      ok: true,
      message,
      conversation: isConversation,
      };
      }
      const conversation = new Conversation();
      conversation.seller_id = seller_id;
      conversation.client_id = client_id;
      conversation.product_id = product_id;
      await transactionalEntityManager.save(conversation);
      const message = new Message();
      message.author_id = client_id;
      message.text = text;
      message.conversation_id = conversation.id;
      await transactionalEntityManager.save(message);
      await queryRunner.commitTransaction();
      emitter.emit('newMessage', {
      destinator_id: seller_id,
      username,
      conversation_id: conversation.id,
      });
      return {
      ok: true,
      message,
      conversation,
      };
      } catch (error) {
      await queryRunner.rollbackTransaction();
      return {
      ok: false,
      errors: [{ path: 'global', message: error.message }],
      };
      }
      }
      ),

    • @bawad
      @bawad  5 лет назад

      do you get an error?

  • @qwerty01453
    @qwerty01453 5 лет назад

    Next great step would be SSO!

    • @bawad
      @bawad  5 лет назад

      I should do that, it would be fun to make

  • @bulldog2024
    @bulldog2024 5 лет назад

    Almost sounds like you could have caught a little strep.

    • @bawad
      @bawad  5 лет назад

      yeah this was my guess

  • @tjalferes
    @tjalferes 5 лет назад

    thanks

  • @dormammun
    @dormammun 4 года назад

    Hello Ben! Thank you for your work and inspiration! Can you tell me how you test authentication?
    When I use `createTestClient` from `apollo-server-express` context get empty object, without `express` `req` and I can't find solution to run `query` or `mutation` and pass headers with them.
    This is my get context function: github.com/team-organizer/team-organizer.core/blob/master/src/app/lib/get-context.ts
    Test: github.com/team-organizer/team-organizer.core/blob/e161d6b346095331f153d9e65ce4e16e66c6769e/src/auth/__tests__/auth.resolver.test.ts#L107

    • @bawad
      @bawad  4 года назад +1

      ruclips.net/video/fxYcbw56mbk/видео.html
      ruclips.net/video/zR8jKR9hnFA/видео.html

    • @dormammun
      @dormammun 4 года назад

      @@bawad Thank you! If you interest I found a solution with supertest, github.com/apollographql/apollo-server/issues/2277#issuecomment-598293528, that's like full e2e test