[英]How to redirect to a login page if Flutter API response is unauthorized?
我正在构建一个 Flutter 应用程序,它使用 Golang API 来获取数据。 如果 JWT 令牌无效,则 API 将返回 401 未授权。 如果响应状态为 401,如何在任何 API 调用上重定向到登录页面?
这是我的 flutter 代码:
main.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
Provider.debugCheckInvalidValueType = null;
AppLanguage appLanguage = AppLanguage();
await appLanguage.fetchLocale();
runApp(MyApp(
appLanguage: appLanguage,
));
}
class MyApp extends StatelessWidget {
final AppLanguage appLanguage;
MyApp({this.appLanguage});
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: providers,
child: MaterialApp(
localizationsDelegates: [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
initialRoute: RoutePaths.Login,
onGenerateRoute: Router.generateRoute,
)
);
}
}
表.dart
class Tables extends StatelessWidget {
const Tables({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BaseWidget<TablesModel>(
model: TablesModel(api: Provider.of(context, listen: false)),
onModelReady: (model) => model.fetchTables(),
builder: (context, model, child) => model.busy
? Center(
child: CircularProgressIndicator(),
)
: Expanded(
child: GridView.builder (
---
tables_model.dart
class TablesModel extends BaseModel {
Api _api;
TablesModel({@required Api api}) : _api = api;
List<Tbl> tables;
Future fetchTables() async {
setBusy(true);
tables = await _api.getTables();
setBusy(false);
}
@override
void dispose() {
print('Tables has been disposed!!');
super.dispose();
}
}
api.dart
Future<List<Tbl>> getTables() async {
var tables = List<Tbl>();
try {
var response = await http.get('$_baseUrl/tables/list');
var parsed = json.decode(response.body) as List<dynamic>;
if (parsed != null) {
for (var table in parsed) {
tables.add(Tbl.fromJson(table));
}
}
} catch (e) {print(e); return null;}
return tables;
}
由于您的树中已经有一个MaterialApp
并且已注册命名路由,因此这应该像添加一个调用以在您获得响应的同时推送您的登录页面一样简单。
首先,您应该修改getTables
以使用Response
object 的statusCode
属性检查状态代码的response
,并显示以下代码块:
var response = await http.get('$_baseUrl/tables/list');
if(response.statusCode == 401) {
//Act on status of 401 here
}
现在您有了一种检查响应何时具有状态码 401 的方法,您可以使用Navigator
导航到您的登录页面。 Navigator
需要BuildContext
,因此必须将其传递给getTables
function。
这涉及将getTables
修改为:
Future<List<Tbl>> getTables(BuildContext context) async {
并且fetchTables
需要进行类似的更改:
Future fetchTables(BuildContext context) async {
然后,在调用这些方法的地方,将context
向下传递:
在Tables
中
model.fetchTables(context)
在TablesModel
Future fetchTables(BuildContext context) async {
setBusy(true);
tables = await _api.getTables(context);
setBusy(false);
}
最后在getTables
中,您使用传递的context
来使用Navigator
:
Future<List<Tbl>> getTables(BuildContext context) async {
var tables = List<Tbl>();
try {
var response = await http.get('$_baseUrl/tables/list');
//Check response status code
if(response.statusCode == 401) {
Navigator.of(context).pushNamed(RoutePaths.Login);//Navigator is used here to go to login only with 401 status code
return null;
}
var parsed = json.decode(response.body) as List<dynamic>;
if (parsed != null) {
for (var table in parsed) {
tables.add(Tbl.fromJson(table));
}
}
} catch (e) {print(e); return null;}
return tables;
}
而不是Navigator.of(context).pushNamed(RoutePaths.Login);
,您可以使用Navigator.pushNamed(context, RoutePaths.Login);
如果您愿意,但是正如您可以在此答案中看到的那样,它们在内部执行相同的操作。
现在,当状态码为 401 时,用户将被导航到登录屏幕。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.