현재 엑세스 토큰의 유효 기간은 5분, 리프레시 토큰은 하루로 설정되어 있음
그래서 토큰 만료로 인해 중간중간 오류가 발생하는 문제가 생김ㅠㅠ
현재 이런 에러를 처리할 수 있는 로직은???
방법은 다양한데, 그중에서도 가장 평범한 방법인 로그아웃 시켜보자!
리프레시 토큰, 엑세스 토큰을 null 체크만 하고 있음.
그럼 토큰들이 유효 기간이 만료됐든, 안 됐든 지금 무조건 있기만 하면 다음 페이지로 넘겨버림.
그런데 페이지에서 리프레시 토큰, 엑세스 토큰이 필요한 API를 사용 중이라면,
이 토큰들은 유효하지 않아서 API를 쓰지 못하게 된다.
그럼 토큰을 재발급 받으면 되겠지? 어떻게? 다시 로그인해서!
새로 리프레시 토큰으로 액세스 토큰을 한 번 새로 발급받으려고 시도 했을 때...
// 요것만!!!
const emulatorIp = '10.0.2.2:3000';
const simulatorIp = '127.0.0.1:3000';
final ip = Platform.isIOS ? simulatorIp : emulatorIp;
그리고 다시 splash_screen.dart로 돌아가서 Dio는 그냥 새로 생성해준다!
추후 전부 통합해서 관리하는 방법 배울 예정...
여기서 추가적으로 에러 발생 시, splash_screen.dart 코드에서 에러를 던져주자!
// ignore_for_file: unused_element
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_actual/common/const/colors.dart';
import 'package:flutter_actual/common/const/data.dart';
import 'package:flutter_actual/common/layout/default_layout.dart';
import 'package:flutter_actual/common/view/root_tab.dart';
import 'package:flutter_actual/user/login_screen.dart';
class SplashScreen extends StatefulWidget {
const SplashScreen({super.key});
State<SplashScreen> createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
void initState() {
super.initState();
// deleteToken();
checkToken();
}
void deleteToken() async {
await storage.deleteAll();
}
// initState()에서는 await 불가능!
// await storage.read(key: REFRESH_TOKEN_KEY);
// await storage.read(key: ACCESS_TOKEN_KEY);
// 함수를 만들어서 쓰자! -> 이제 스토리지로부터 토큰 가져올 수 있음
void checkToken() async {
final refeshToken = await storage.read(key: REFRESH_TOKEN_KEY);
final accessToken = await storage.read(key: ACCESS_TOKEN_KEY);
final dio = Dio();
try {
final resp = await dio.post(
'http://$ip/auth/token',
options: Options(
headers: {
'authorizaiton': 'Bearer $refeshToken',
},
),
);
// 에러 발생 X (정상일 때) => RootTab 으로
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (_) => const RootTab(),
),
(route) => false,
);
} catch (e) {
// 에러 발생 시 => LoginScreen으로
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (_) => const LoginScreen(),
),
(route) => false);
}
}
Widget build(BuildContext context) {
return DefaultLayout(
backgroundColor: PRIMARY_COLOR,
child: SizedBox(
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'asset/img/logo/logo.png',
width: MediaQuery.of(context).size.width / 2,
),
const Text(
'Food Order App',
style: TextStyle(
fontFamily: 'NotoSans',
color: Colors.white,
fontSize: 30,
fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
const CircularProgressIndicator(
color: Colors.white,
)
],
),
),
);
}
}
이전에 작성했던 splash_screen.dart 코드와 조금 달라진 부분을 찾을 수 있을 것!!!
이렇게 하고 재시작 하면...
토큰이 분명 이 안에 들어있음에도 이렇게 로그인 화면이 나온다.
로그인도 잘 된다.
💣 트러블이슈
강의에서는 로그인 하고 재실행 시, 바로 홈화면(RootTab)이 보이는데 왜 나는 다시 로그인 화면이 나올까?
👉 오타 문제였음...
'authorization': 'Bearer $refreshToken'
수정 후 해결!