Глубокая ссылка после аутентификации GitHub во флаттере - PullRequest
0 голосов
/ 23 февраля 2020

Я хочу, чтобы отображался мой экран входа в систему, если пользователь не вошел в систему, и главная страница, которая должна отображаться, если пользователь вошел в систему с устройства. Для аутентификации GitHub открывается браузер, и как только аутентификация прошла успешно, я хочу, чтобы пользователь перенаправлялся на главную страницу, а не на экран входа в систему, но с моим кодом пользователь снова перенаправляется на экран входа в систему. Код для login_screen.dart:

import 'package:flutter/material.dart';
import 'package:githubapp/custom_widgets/custom_login_page.dart';
import 'package:githubapp/screens/user_initial_screen.dart';
import 'package:url_launcher/url_launcher.dart';
import 'dart:async';
import 'package:uni_links/uni_links.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;

class LoginPage extends StatefulWidget {
  @override
  _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  StreamSubscription _subs;

  @override
  void initState() {
    _initDeepLinkListener();
    super.initState();
  }

  @override
  void dispose() {
    _disposeDeepLinkListener();
    super.dispose();
  }

  void _initDeepLinkListener() async {
    _subs = getLinksStream().listen((String link) {
      _checkDeepLink(link);
    }, cancelOnError: true);
  }

  void _checkDeepLink(String link) {
    if (link != null) {
      String code = link.substring(link.indexOf(RegExp('code=')) + 5);
      loginWithGitHub(code)
          .then((firebaseUser) {
        print("LOGGED IN AS: " + firebaseUser.displayName);
        Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (BuildContext context){
          return MainPage();
        }));
      }).catchError((e) {
        print("LOGIN ERROR: " + e.toString());
      });
    }
  }

  void _disposeDeepLinkListener() {
    if (_subs != null) {
      _subs.cancel();
      _subs = null;
    }
  }

  @override
  Widget build(BuildContext context) {
    return customLoginPage(context);
  }
}

const String GITHUB_CLIENT_ID = "My Client Id";
const String GITHUB_CLIENT_SECRET = "My Client Secret";

void onClickGitHubLoginButton() async {
  const String url = "https://github.com/login/oauth/authorize" +
      "?client_id=" + GITHUB_CLIENT_ID +
      "&scope=public_repo%20read:user%20user:email";

  if (await canLaunch(url)) {
    await launch(
      url,
      forceSafariVC: false,
      forceWebView: false,
    );
  } else {
    print("CANNOT LAUNCH THIS URL!");
  }
}

Future<FirebaseUser> loginWithGitHub(String code) async {
  //ACCESS TOKEN REQUEST
  final response = await http.post(
    "https://github.com/login/oauth/access_token",
    headers: {
      "Content-Type": "application/json",
      "Accept": "application/json"
    },
    body: jsonEncode(GitHubLoginRequest(
      clientId: GITHUB_CLIENT_ID,
      clientSecret: GITHUB_CLIENT_SECRET,
      code: code,
    )),
  );

  GitHubLoginResponse loginResponse =
  GitHubLoginResponse.fromJson(json.decode(response.body));

  final AuthCredential credential = GithubAuthProvider.getCredential(
    token: loginResponse.accessToken,
  );

  final FirebaseUser user = (await FirebaseAuth.instance.signInWithCredential(credential)).user;
  return user;
}

class GitHubLoginRequest {
  String clientId;
  String clientSecret;
  String code;

  GitHubLoginRequest({this.clientId, this.clientSecret, this.code});

  dynamic toJson() => {
    "client_id": clientId,
    "client_secret": clientSecret,
    "code": code,
  };
}

class GitHubLoginResponse {
  String accessToken;
  String tokenType;
  String scope;

  GitHubLoginResponse({this.accessToken, this.tokenType, this.scope});

  factory GitHubLoginResponse.fromJson(Map<String, dynamic> json) =>
      GitHubLoginResponse(
        accessToken: json["access_token"],
        tokenType: json["token_type"],
        scope: json["scope"],
      );
}

Код для main.dart:

import 'package:flutter/material.dart';
import 'package:githubapp/auth/login_screen.dart';
import 'package:githubapp/screens/user_initial_screen.dart';
import 'package:githubapp/screens/user_profile_page.dart';
import 'package:firebase_auth/firebase_auth.dart';


void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  // This widget is the root of your application.
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  String routeToMainPage = 'mainPage';
  String routeToLoginPage = 'loginPage';
  String routeInitial = '';

  getCurrentUser() async {
    FirebaseUser user = await FirebaseAuth.instance.currentUser();
    return user;
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    if(getCurrentUser() != null){
      routeInitial = routeToMainPage;
    } else {
      routeInitial = routeToLoginPage;
    }
  }
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'GitHub',
     initialRoute: '/${routeInitial}',
      routes: {
        '/mainPage': (context) => MainPage(),
        '/loginPage': (context) => LoginPage(),
        '/userprofile': (context) => UserProfilePage(),
      },
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
    );
  }
}

Код, в котором присутствует функция MainPage (),

import 'package:flutter/material.dart';
import 'package:githubapp/custom_widgets/custom_appbar.dart';

class MainPage extends StatefulWidget {
  @override
  _MainPageState createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      child: Scaffold(
        appBar: customAppBar(context),
//        body: ,
      ),
      onTap: () {
        FocusScopeNode currentFocus = FocusScope.of(context);
        if (!currentFocus.hasPrimaryFocus) {
          currentFocus.unfocus();
        }
      },
    );
  }
}

Для URL обратного вызова авторизации, который мы должны ввести при получении ClientId и ClientSecret от GitHub, это appname: // auth? Code = auth /

1 Ответ

0 голосов
/ 23 февраля 2020

Вы должны перейти на главную страницу после успешного входа в систему

void _checkDeepLink(String link) {
    if (link != null) {
      String code = link.substring(link.indexOf(RegExp('code=')) + 5);
      loginWithGitHub(code)
          .then((firebaseUser) {
        print("LOGGED IN AS: " + firebaseUser.displayName);
        Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (BuildContext context){
          return MainPage();
        }));
      }).catchError((e) {
        print("LOGIN ERROR: " + e.toString());
      });
    }
  }
...