Flutterando / modular

A smart project structure
https://pub.dev/packages/flutter_modular
Other
1.31k stars 253 forks source link

RouteGuard is never fired #24

Closed felipewom-zz closed 4 years ago

felipewom-zz commented 4 years ago
class AppModule extends MainModule {
  @override
  List<Bind> get binds => [
        Bind((i) => AppController()),
      ];
  @override
  List<Router> get routers => [
        Router('/', module: LoginModule()),
        Router('/home', module: HomeModule(), guards: [AppGuard()]),
      ];
  @override
  Widget get bootstrap => AppWidget();
  static Inject get to => Inject<AppModule>.of();
}

class AppGuard implements RouteGuard {
  @override
  bool canActivate(String url) {
    return false;
  }
}

Fala pessoal, mesmo forçando retorno para false e debugando, o canActivate não esta sendo acionado, a implementação do RouteGuard está correta? Teria algum outro material/documentação para olhar sobre segurança de rotas?

Abraço!

jacobaraujo7 commented 4 years ago

Os testes unitários estão Ok, mas eu n testei direto no App. Estarei olhando aqui. O que achou nas suas debugações?

jacobaraujo7 commented 4 years ago

testa a versão v0.3.3+1

felipewom-zz commented 4 years ago

Fala jacob, talvez eu esteja implementado errado... segue o link... https://github.com/felipewom/flutter_app_modular Me parece que no else no metodo _searchInModule na classe modular_base

else {
        if (searchRoute(route, tempRouteName, path)) {
          var guards = _prepareGuardList(_masterRouteGuards, route.guards);
          _masterRouteGuards = null;
          RouteGuard guard;
          try {
            guard = guards.length == 0
                ? null
                : guards.firstWhere((guard) => !guard.canActivate(path),
                    orElse: null);
          } catch (e) {}

          return guard == null ? route : null;
        }
      }

Não entra, desculpa a falta de detalhes, não tive muito tempo para debugar e ajudar.. De qualquer forma curto muito as libs que vocês lançaram e já usava slidy com BLoC rxdart, me interessou muito quando viraram a chave para flutter_modular com mobx, estou me aventurando, essa questão de guards, canActivate é bem semelhante ao Angular, parece ser mais intuitiva...

Obrigado pela força!

jacobaraujo7 commented 4 years ago

Na nova versão continua não entrando?

felipewom-zz commented 4 years ago

Sim, atualizei para flutter_modular: ^0.3.3+1

GuilhermeVendramini commented 4 years ago

Estou utilizando a versão ^0.4.2.

Pelos meus testes o Guard não é chamado quando no Router chama um "module": Router('/register', module: RegisterModule(), guards: [AuthenticatedUserGuard()]),

Mas quando é chamado um "child" ele funciona:

Router('/', child: (_, args) => CoreSplashPage(), guards: [AuthenticatedUserGuard()]),

Print em anexo.

print

GuilhermeVendramini commented 4 years ago

Não sei se é a melhor forma de resolver o problema, mas segue um patch que aparentemente está funcionando. routeGuard.txt

GuilhermeVendramini commented 4 years ago

Obs.: Vai ser preciso implementar o " onUnknownRoute" no MaterialApp apontando para uma "PageNotFound", pois a logica aplicada vai retornar "null".

jacobaraujo7 commented 4 years ago

Vou testar o patch e ja retorno

jacobaraujo7 commented 4 years ago

Por favor, testem a versão flutter_modular: ^0.4.3-dev.1

me digam se o problema resolveu para vcs

jacobaraujo7 commented 4 years ago

testei aqui, vou adicionar esse patch a nova versão. Por enquant vou fechar essa issue. Mas pode ser aberta a qualquer momento

GuilhermeVendramini commented 4 years ago

Fim de semana vou ver se pego pra testar com mais detalhes, qualquer coisa do um toque. Valeus.

jaykon-w commented 4 years ago

Os guard estão sendo testados, mas ou ele retorna null e cai em uma excessão:

Could not find a generator for route RouteSettings("/", null) in the _WidgetsAppState.

ou eu tento fazer um redirect antes de retornar false no canActivate e ele retorna esse outro erro:

'package:flutter/src/widgets/navigator.dart': Failed assertion: line 1782 pos 12: '!_debugLocked': is not true.

Segue o trecho:

  @override
  List<Router> get routers => [
        Router('/', module: InAppModule(), guards: [MyGuard()]),
        Router('/login', module: LoginModule()),
      ];

........

class MyGuard implements RouteGuard {
  final SessionController _sessionController = Modular.get();

  @override
  bool canActivate(String url) {
    var canGo = _sessionController.session != null;
    if (!canGo) Get.offNamed(AppRoutes.login);
    return canGo;
  }
}
GuilhermeVendramini commented 4 years ago

Acredito que a intenção realmente é retornar null. Ae no caso você teria que implementar o "onUnknownRoute" no MaterialApp (no meu caso eu criei uma pageNotFound e chamo ela no onUnknownRoute). Mas a sua solução parece ser boa também, não vejo problemas.

jaykon-w commented 4 years ago

Assim como o @GuilhermeVendramini falou, vai ser preciso implementar tbm algo para quando a rota não for encontrada.

Sugestão:

@override
List<Router> get routers => [
    Router('/', module: InAppModule(), guards: [MyGuard()]),
    Router('/login', module: LoginModule()),
    Router.otherwise(redirect: '/login', /* poderia tbm ter as props module e child  */)
  ];

A class Guard tbm poderia ter um método:

@override
String toRedirect(String lastActivatedRoute, String blockedRoute) {
    return lastActivatedRoute ?? '/' ;
}

Esse método diria para que rota aquele guard redirecionaria caso fosse bloqueado. Isso seria útil para redirecionar para uma tela de login, ou mesmo para a ultima rota que o usuário passou. No caso do usuário (Web), digitar diretamente a rota bloqueada na url, lastActivatedRoute seria null, nesse caso poderia retorna-lo para a rota inicial '/' ou outra qualquer.

jacobaraujo7 commented 4 years ago

Reabri a issue, realmente ainda não chegamos a uma solução definitiva

jacobaraujo7 commented 4 years ago

Na acabei de aceitar um pull request q talvez corrija esse problema. Se puderem testar

jacobaraujo7 commented 4 years ago

teste das rotas me pareceu bem sucedido por enquanto. Se houver algum problema é só reabrir esse tópico! Obrigado