卡住了Flutter的Auth架构

时间:2020-09-28 19:48:29

标签: flutter dart

好的,大家好,这是一个问题:

我已经开始在移动前端使用Flutter,这非常好。 但是我不明白处理jwt令牌并重定向(如果存在)的想法。

考虑小型应用程序,让我简化一下:


final storage = FlutterSecureStorage(); # init storage here?

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    return MaterialApp(
      theme: ThemeData.dark(),
      home: LoginPage(), # want home page actually, smth like if storage is empty, then call loginpage, if storage is not empty - try to make http request, if request is okay and data received - show homepage, if request is rejected - login to obtain new jwt
    );
  }
}

http请求:

Future<User> userLogin(String login, String password) async {
    Response response = await post('$_apiUrl' + '/' + '$_loginUrl',
        headers: <String, String>{
          'Content-Type': 'application/json; charset=UTF-8',
        },
        body: jsonEncode(<String, String>{
          'login': login,
          'password': password,
        }));
    if (response.statusCode == 200) {
      return User.fromJson(json.decode(response.body));
    } else {
      throw HttpException(
          'Error making login request. Status code: ${response.statusCode}');
    }
  }

用户类别:

class User {

  final String token;
  final String uuid;
  final String login;
  final String email;
  final String firstName;
  final String lastName;

  User({this.token, this.uuid, this.login, this.email, this.firstName, this.lastName});

  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      token: json['token'],
      uuid: json['user']['uuid'],
      login: json['user']['login'],
      email: json['user']['email'],
      firstName: json['user']['firstName'],
      lastName: json['user']['lastName'],
    );
  }
}

所以现在如何工作:

现在在主文件中,我用一个按钮调用登录页面:

FlatButton(
                child: Text(
                  'Sign in',
                  style: TextStyle(
                    color: Colors.black,
                  ),
                ),
                color: Colors.white,
                onPressed: () {
                  Future<User> user = ApiRequestController().userLogin('alex', 'alex123');
                  Navigator.push(context, MaterialPageRoute(builder: (context) {
                    return UserProfile(userData: user,);
                  }));
                },
              ),

然后我被重定向到用户个人资料,没什么有趣的:

class UserProfile extends StatefulWidget {
  UserProfile({this.userData});
  final userData;

  @override
  _UserProfileState createState() => _UserProfileState();
}

class _UserProfileState extends State<UserProfile> {
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    futureUser = widget.userData;
    print(futureUser);
  }

  Future<User> futureUser;

  @override
  Widget build(BuildContext context) {
common stuff like scaffold etc

然后我建立一个配置文件:

FutureBuilder<User>(
                future: futureUser,
                builder: (context, snapshot) {
                  if (snapshot.hasData) {
                    dynamic userProfile = snapshot.data;
                    return Column(
                      children: [
                        Container(
                          child: ListTile(
                            title: Text(
                              'login: ' + '${userProfile.login}',
                              style: TextStyle(
                                color: Colors.black,
                              ),
                            ),
                          ),
                        ),
                        Container(
                          child: ListTile(
                            title: Text(
                              'uuid: ' + '${userProfile.uuid}',
                              style: TextStyle(
                                color: Colors.black,
                              ),
                            ),
                          ),
                        ),
                        Container(
                          child: ListTile(
                            title: Text(
                              'First name: ' + '${userProfile.firstName}',
                              style: TextStyle(
                                color: Colors.black,
                              ),
                            ),
                          ),
                        ),
                        Container(
                          child: ListTile(
                            title: Text(
                              'Last name: ' + '${userProfile.lastName}',
                              style: TextStyle(
                                color: Colors.black,
                              ),
                            ),
                          ),
                        ),
                        Container(
                          child: ListTile(
                            title: Text(
                              'Auth token: ' + '${userProfile.token}',
                              style: TextStyle(
                                color: Colors.black,
                              ),
                            ),
                          ),
                        ),
                      ],
                    );
                  } else if (snapshot.hasError) {
                    return Text('${snapshot.error}');
                  }
                  return CircularProgressIndicator();
                },
              ),

界面经过简化,易于理解。

所以我现在拥有的是主dart文件,在这里我称为登录屏幕(不是主屏幕,因为我无法知道如何使用令牌),在这里我将异步http请求调用到api,那么我就是重定向到用户个人资料。

想法很简单:

  1. 应用已打开->使用现有的auth标头发送http请求,如果答案为200,则显示首页
  2. 如果答案不是200(令牌已过期/损坏/不存在,请在服务器端选中),然后导航用户至登录屏幕以获取新的身份验证令牌
  3. 如何正确存储该死的jwt令牌-_-?我对期货,普通请求已经尝试了多次,但我不了解在多个屏幕之间解析令牌的想法。

我该怎么办?在哪里初始化令牌?存放在哪里?如何从其他小部件中调用它? 我已经读过有关InheritedWidget的信息。但是,即我的主页已经扩展了StatefulWidget,并且没有多重继承。扩展到用户类还是什么?

所以我坚持这个简单的目标,无法继续前进。只需检查令牌是否存在->显示主页,否则-显示登录名。获得正确的令牌后-我们可以使用整个应用程序,并在第一个登录屏幕上收到带有身份验证令牌的每个请求。

在哪里初始化令牌?我应该在哪里继承InheritedWidget?模型? ViewPage?哪里? 架构失败:(

非常感谢您的帮助!预先感谢

0 个答案:

没有答案