๐Ÿ“ Log in Process Summary

j00b33ยท2022๋…„ 4์›” 12์ผ
0

CodeCamp BE 02

๋ชฉ๋ก ๋ณด๊ธฐ
21/30

1. User-password Encryption

JWT : JSON Web Token is mostly used for data encryption

Here, key is the string-type password
--> Using this key, only the one who knows the password is able to access for decoding.


2. Authentication / Authorization

Authentication

// ============== Authorization Resolver ==============

@Mutation(() => String)
  async login(
    @Args('email') email: string, //
    @Args('password') password: string,
  ) {
    // 1. ๋กœ๊ทธ์ธ (DB์—์„œ ์ด๋ฉ”์ผ๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ผ์น˜ํ•˜๋Š” ์œ ์ € ์ฐพ๊ธฐ)
    const user = await this.userService.findOne({ email });

    // 2. ์ผ์น˜ํ•˜๋Š” ์œ ์ €๊ฐ€ ์—†์œผ๋ฉด ==> ์—๋Ÿฌ ๋˜์ง€๊ธฐ
    if (!user) {
      throw new UnprocessableEntityException('์กด์žฌํ•˜์ง€ ์•Š๋Š” ์ด๋ฉ”์ผ์ž…๋‹ˆ๋‹ค'); // 422 error -> ๋กœ์ง์ƒ์— ๋ฌธ์ œ๊ฐ€ ์žˆ์„๋•Œ
    }

    // 3. ์ผ์น˜ํ•˜๋Š” ์œ ์ €๊ฐ€ ์žˆ์ง€๋งŒ ์•”ํ˜ธ๊ฐ€ ํ‹€๋ ธ๋‹ค๋ฉด ==> ์—๋Ÿฌ ๋˜์ง€๊ธฐ
    const isAuth = await bcrypt.compare(password, user.password); // ์ˆœ์„œ ์ค‘์š”ํ•จ
    if (!isAuth) {
      throw new UnprocessableEntityException('์•”ํ˜ธ๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค');
    }

    // 4. ์ผ์น˜ํ•˜๋Š” ์œ ์ €๊ฐ€ ์žˆ์œผ๋ฉด ==> accessToken (JWT) ํ† ํฐ ๋งŒ๋“ค์–ด์„œ ํ”„๋ก ํŠธ์•ค๋“œ์— ์ฃผ๊ธฐ
    return this.authService.getAccessToken({ user });
  }
// ============== Authentication Services ==============

@Injectable()
export class AuthService {
  constructor(private readonly jwtService: JwtService) {}
  getAccessToken({ user }) {
    // sub์•ˆํ•˜๊ณ  idํ•ด๋„ ๋จ - just written in jwt docs
    return this.jwtService.sign(
      { email: user.email, sub: user.id },
      { secret: 'myAccessKey', expiresIn: '1h' },
    );
  }
}

Authorization

file route - commons/auth

export class GqlAuthAccessGuard extends AuthGuard('access') {
  getRequest(context: ExecutionContext) {
    // ๊ฒ€์ฆํ•˜๋Š” ํ•จ์ˆ˜ ==> ํ•จ์ˆ˜๋ฅผ ๋ฐ”๊ฟ”์น˜๊ธฐํ•ด์ฃผ๋Š”๊ฑฐ์ž„ AuthGuard('access)๋ฅผ get Request๋กœ ๋ฐ”๊ฟ”์คŒ
    const ctx = GqlExecutionContext.create(context);
    return ctx.getContext().req;
  }
}

==> gql ํ’€์–ด๋‚ด๊ธฐ (=guard ๋šซ๊ธฐ)

@Injectable()
export class JwtAccessStrategy extends PassportStrategy(Strategy, 'access') {
  // ์—ฌ๊ธฐ ์ž‘์„ฑํ•œ๋Œ€๋กœ userResolver์˜ fetchUser ๊ฒ€์ฆํ•˜๊ฒ ๋‹ค

  constructor() {
    super({
      // ๊ฒ€์ฆ๋ถ€ (๋จผ์ € ์‹คํ–‰๋˜๊ณ  ๊ฒ€์ฆ์— ์„ฑ๊ณตํ•˜๋ฉด)
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: 'myAccessKey',
    });
  }

  // ๊ฒ€์ฆ ์™„๋ฃŒ๋˜๋ฉด ์‹คํ–‰  (๊ฒ€์ฆ ์„ฑ๊ณต)
  validate(payload) {
    console.log(payload);
    return {
      email: payload.email,
      id: payload.sub,
    };
  }
}

profile
์ฝฑใ…†l

0๊ฐœ์˜ ๋Œ“๊ธ€