当前位置: 首页 > 知识库问答 >
问题:

成功身份验证后,如何处理经过身份验证的路由及其重定向?

席嘉祯
2023-03-14

Flatter Web(Navigator 2.0/Router API):如何处理经过身份验证的路由及其成功身份验证后的重定向?

e、 g.我的系统中有这种路由

/book/xyz (authenticated user)
/author/abc/book/xyz (authenticated user)
/authentication (non-authenticated user)
/info (non-authenticated user)

若用户直接打开这个URL,我想让用户先登录,那个么路由将被重定向到。。

/authentication

一旦登录,我想用户导航以前打开的网址,如果有任何其他主页。。

似乎这种事情可能会有所帮助,任何想法——我们如何才能实现类似的事情?https://stackoverflow.com/a/43171515/2145844

我尝试了几个导航2.0/路由器API的示例,是的,我可以理解一些概念。.

一些参考资料,我已经看过了。。

https://medium.com/flutter/learning-flutters-new-navigation-and-routing-system-7c9068155adehttps://github.com/orestesgaolin/navigator_20_examplehttps://github.com/flutter/flutter/tree/master/dev/benchmarks/test_apps/stocks

共有2个答案

茅星雨
2023-03-14

您可以使用qlevar_router来做这件事。从这个例子中,在链接中,您可以定义一个带有重定向的中间件来检查用户是否可以访问这个页面或它的子页面,否则只需给出重定向到的路由。你可以在示例项目中看到这一点同样。如果你给访问子4的权利,它将转到子4,否则你将被导航到子2

佟英武
2023-03-14

这里是如何做到这一点使用虚拟路由器

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:vrouter/vrouter.dart';

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

class Book {
  final String title;
  final Author author;

  Book(this.title, this.author);
}

class Author {
  String name;

  Author(this.name);
}

class AppState extends ChangeNotifier {
  bool _isAuthenticated = false;

  bool get isAuthenticated => _isAuthenticated;

  void authenticate() {
    if (isAuthenticated) return;
    _isAuthenticated = true;
    notifyListeners();
  }
}

class BooksApp extends StatelessWidget {
  final List<Book> books = [
    Book('Stranger in a Strange Land', Author('Robert A. Heinlein')),
    Book('Foundation', Author('Isaac Asimov')),
    Book('Fahrenheit 451', Author('Ray Bradbury')),
  ];

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (_) => AppState(),
      child: Builder(
        builder: (BuildContext context) {
          return VRouter(
            routes: [
              VWidget(path: '/login', widget: AuthenticationScreen()),
              VWidget(path: '/info', widget: InfoWidget()),
              VGuard(
                beforeEnter: (vRedirector) =>
                    authenticationCheck(context, vRedirector: vRedirector),
                stackedRoutes: [
                  VWidget(
                    path: '/',
                    widget: BooksListScreen(books: books),
                    stackedRoutes: [
                      VWidget(
                        path: r'book/:bookId(\d+)',
                        widget: Builder(builder: (BuildContext context) {
                          return BookDetailsScreen(
                            book: books[int.parse(context.vRouter.pathParameters['bookId']!)],
                          );
                        }),
                      ),
                    ],
                  ),
                  VWidget(
                    path: '/authors',
                    widget: AuthorsListScreen(authors: books.map((e) => e.author).toList()),
                    stackedRoutes: [
                      VWidget(
                        path: r'/author/:authorId(\d+)',
                        widget: Builder(builder: (BuildContext context) {
                          return AuthorDetailsScreen(
                            author: books[int.parse(context.vRouter.pathParameters['authorId']!)]
                                .author,
                          );
                        }),
                      ),
                    ],
                  ),
                ],
              ),
            ],
          );
        },
      ),
    );
  }

  Future<void> authenticationCheck(BuildContext context, {required VRedirector vRedirector}) async {
    if (!Provider.of<AppState>(context, listen: false).isAuthenticated) {
      vRedirector.to('/login', queryParameters: {'redirectedFrom': '${vRedirector.toUrl}'});
    }
  }
}

class AuthenticationScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: ElevatedButton(
        onPressed: () {
          Provider.of<AppState>(context, listen: false).authenticate();
          context.vRouter.to(context.vRouter.queryParameters['redirectedFrom'] == null
              ? '/'
              : context.vRouter.queryParameters['redirectedFrom']!);
        },
        child: Text('Click to login'),
      ),
    );
  }
}

class InfoWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text('Some info but actually there is nothing'),
    );
  }
}


class BooksListScreen extends StatelessWidget {
  final List<Book> books;

  BooksListScreen({required this.books});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: ListView(
        children: [
          for (var book in books)
            ListTile(
              title: Text(book.title),
              subtitle: Text(book.author.name),
              onTap: () => context.vRouter.to('/book/${books.indexOf(book)}'),
            )
        ],
      ),
    );
  }
}

class AuthorsListScreen extends StatelessWidget {
  final List<Author> authors;

  AuthorsListScreen({required this.authors});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: ListView(
        children: [
          ElevatedButton(
            onPressed: () => context.vRouter.to('/'),
            child: Text('Go to Books Screen'),
          ),
          for (var author in authors)
            ListTile(
              title: Text(author.name),
              onTap: () => context.vRouter.to('/author/${authors.indexOf(author)}'),
            )
        ],
      ),
    );
  }
}

class BookDetailsScreen extends StatelessWidget {
  final Book book;

  BookDetailsScreen({required this.book});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(book.title, style: Theme.of(context).textTheme.headline6),
            ElevatedButton(
              onPressed: () {
                context.vRouter.to('/author/${context.vRouter.pathParameters['bookId']}');
              },
              child: Text(book.author.name),
            ),
          ],
        ),
      ),
    );
  }
}

class AuthorDetailsScreen extends StatelessWidget {
  final Author author;

  AuthorDetailsScreen({required this.author});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(author.name, style: Theme.of(context).textTheme.headline6),
          ],
        ),
      ),
    );
  }
}

诀窍是使用VGuard,它在进入stackedRoutes之前检查用户是否经过身份验证。

我使用queryParameters来存储它从哪里重定向的用户,但是如果你不想用户从哪里重定向出现在url中,你可以使用历史状态。话虽如此,在这种情况下,我仍然更喜欢queryParameters,因为它允许链接共享。

 类似资料:
  • 我试图在登录symfony2应用程序后实现重定向,以便在我的用户是否有一个属性时重定向。我已在项目的Handler文件夹中创建了AuthenticationSuccessHandler.php类: 但是当我登录时,我得到一个错误: 注意:未定义的属性:Me\MyBundle\Handler\AuthenticationSuccessHandler::$router in/var/www/MyBun

  • 试图使某些路由需要身份验证。 我有这个: 注意:是的,身份验证服务正常工作。 对于每个路由,我检查用户是否经过身份验证,如果没有,那么我想将他们重定向到登录页面,如果他们是,那么它将在第一个页面上着陆,路由为"/"。 我得到的只是: 我哪里做错了?

  • 我正在laravel中创建一个多身份验证系统,其中有两种类型的用户:管理员(由我创建)和用户(使用本地laravel身份验证系统)。 如果我以用户身份登录,当我尝试访问登录页面时,当我已经登录,它会将我重定向回仪表板,但如果我以管理员身份登录,当我再次访问管理员登录页面时,它会让我再次登录,尽管已经作为管理员登录。 以下是我的重定向身份验证类代码: 有人能解释一下发生了什么事吗?

  • 身份验证 PDF版下载 企业应用中的URL链接可以通过OAuth2.0验证接口来获取员工的身份信息。 通过此接口获取员工身份会有一定的时间开销。对于频繁获取员工身份的场景,建议采用如下方案: 企业应用中的URL链接直接填写企业自己的页面地址; 员工跳转到企业页面时,企业校验是否有代表员工身份的cookie,此cookie由企业生成; 如果没有获取到cookie,重定向到OAuth验证链接,获取员工

  • 成员身份验证 PDF版下载 OAuth2简介 如流平台提供了OAuth的授权登录方式,可以使如流客户端(移动端或者桌面端内嵌打开)打开的网页获取成员的身份信息,从而免去登录环节。 企业应用中的URL链接(包括自定义菜单或者消息中的链接),均可通过OAuth2.0验证接口来获取成员的身份信息(UserId)。 第一步:构造网页授权链接 获取用户在如流客户端打开应用(或者链接)时的用户身份,如流提供两

  • 我目前正在使用FirebaseAuth和web小部件库firebaseui web开发基于VueJS的登录流原型。 成功认证后(无论是< code>password还是< code>google provider ),小部件加载栏会不断重复,firebaseui-web不会触发其< code > signinseccesswithauthresult 回调。但是对< code > identity