스루나루 2024. 4. 17. 21:34
728x90
728x90

 

 

 인증 

 - 서버와 통신하는 사용자의 정보와 유효성 검증 

 - 이전에서는 그냥 로컬에서 사용을 했으니까 괜찮았는데 서버와 연결하면 해당 인증 절차는 복잡해진다.  왜냐하면 사용자가 나 뿐만이 아니라 다른 사용자의 데이터도 존재하기 때문에 해당 데이터를 구분하고 요청에 맞는 데이터를 반환하는 것이 중요 

 

 JWT

 - 사용자 요청을 확인할 때마다 아이디 비번 입력하게 만들면 그 서비스 불편해서 아무도 안 쓴다 

 - 그런거 없이 JWT를 사용해서 인증을 처리 

 - 액세스토큰 ( 정보 접근 시 사용 ) , 리프레스 토큰 ( 액세스 토큰 만료시 사용 ) 으로 구성

 

 

class AuthRepository {
  final _dio = Dio();
  final _targetUrl = 'http://${Platform.isAndroid ? '10.0.2.2' : 'localhost'}:3000/auth';

  Future<({String refreshToken, String accessToken})> register({
    required String email,
    required String password,
  }) async {
    final result = await _dio.post(
      '$_targetUrl/register/email',
      data: {
        'email': email,
        'password': password,
      },
    );

    return (refreshToken: result.data['refreshToken'] as String, accessToken: result.data['accessToken'] as String);
  }

  Future<({String refreshToken, String accessToken})> login({
    required String email,
    required String password,
  }) async {
    final emailAndPassword = '$email:$password';
    Codec<String, String> stringToBase64 = utf8.fuse(base64);

    final encoded = stringToBase64.encode(emailAndPassword);

    final result = await _dio.post(
      '$_targetUrl/login/email',
      options: Options(
        headers: {
          'authorization': 'Basic $encoded',
        },
      )
    );

    return (refreshToken: result.data['refreshToken'] as String, accessToken: result.data['accessToken'] as String);
  }

  Future<String> rotateRefreshToken({
    required String refreshToken,
  }) async {
    // Refresh Token을 Header에 담아서 Refresh Token 재발급 URL에 요청을 보냅니다.
    final result = await _dio.post(
      '$_targetUrl/token/refresh',
        options: Options(
          headers: {
            'authorization': 'Bearer $refreshToken',
          },
        )
    );

    return result.data['refreshToken'] as String;
  }

  Future<String> rotateAccessToken({
    required String refreshToken,
  }) async {
    // Refresh Token을 Header에 담아서 Access Token 재발급 URL에 요청을 보냅니다.
    final result = await _dio.post(
      '$_targetUrl/token/access',
        options: Options(
          headers: {
            'authorization': 'Bearer $refreshToken',
          },
        )
    );

    return result.data['accessToken'] as String;
  }
}

 

 

토큰 업데이트용 프로바이더 설정 

Future<void> register({
    required String email,
    required String password,
  }) async {
    final resp = await authRepository.register(
      email: email,
      password: password,
    );

    updateTokens(
      refreshToken: resp.refreshToken,
      accessToken: resp.accessToken,
    );
  }

 

 

이 글은 골든래빗 《Must Have 코드팩토리의 플러터 프로그래밍 2판》의 스터디 내용 입니다. 

728x90
728x90