且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使用 Firebase_Auth 和 Flutter 登录 Twitter

更新时间:2023-11-28 12:12:22

我使用 3 个资源解决了这个问题:

I was able to solve this using 3 resources:

  1. Flutter Facebook 登录 (与 Firebase)在 2020 年文章
  2. 使用 Twitter 登录 指南
  3. Dart OAuth1
  1. The Flutter Facebook Sign In (with Firebase) in 2020 article
  2. The Log in with Twitter guide
  3. The Dart OAuth1 library

最终,我能够完全删除 flutter_twitter 包,但仍然支持 Sign在推特上.

Ultimately, I was able to completely remove the flutter_twitter package, yet still support Sign in with Twitter.

类似于 Facebook 解决方案中概述的 CustomWebView,我创建了一个 TwitterLoginScreen 如下:

Similar to the CustomWebView outlined in the Facebook solution, I created a TwitterLoginScreen like:

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
import 'package:oauth1/oauth1.dart';

/// Twitter Login Screen.
/// See [Log in with Twitter](https://developer.twitter.com/en/docs/basics/authentication/guides/log-in-with-twitter).
class TwitterLoginScreen extends StatefulWidget {
  final twitterPlatform = Platform(
    'https://api.twitter.com/oauth/request_token', // temporary credentials request
    'https://api.twitter.com/oauth/authorize', // resource owner authorization
    'https://api.twitter.com/oauth/access_token', // token credentials request
    SignatureMethods.hmacSha1, // signature method
  );

  final ClientCredentials clientCredentials;
  final String oauthCallbackHandler;

  TwitterLoginScreen({
    @required final String consumerKey,
    @required final String consumerSecret,
    @required this.oauthCallbackHandler,
  }) : clientCredentials = ClientCredentials(consumerKey, consumerSecret);

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

class _TwitterLoginScreenState extends State<TwitterLoginScreen> {
  final flutterWebviewPlugin = FlutterWebviewPlugin();

  Authorization _oauth;

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

    // Initialize Twitter OAuth
    _oauth = Authorization(widget.clientCredentials, widget.twitterPlatform);

    flutterWebviewPlugin.onUrlChanged.listen((url) {
      // Look for Step 2 callback so that we can move to Step 3.
      if (url.startsWith(widget.oauthCallbackHandler)) {
        final queryParameters = Uri.parse(url).queryParameters;
        final oauthToken = queryParameters['oauth_token'];
        final oauthVerifier = queryParameters['oauth_verifier'];
        if (null != oauthToken && null != oauthVerifier) {
          _twitterLogInFinish(oauthToken, oauthVerifier);
        }
      }
    });

    _twitterLogInStart();
  }

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

  Future<void> _twitterLogInStart() async {
    assert(null != _oauth);
    // Step 1 - Request Token
    final requestTokenResponse =
        await _oauth.requestTemporaryCredentials(widget.oauthCallbackHandler);
    // Step 2 - Redirect to Authorization Page
    final authorizationPage = _oauth.getResourceOwnerAuthorizationURI(
        requestTokenResponse.credentials.token);
    flutterWebviewPlugin.launch(authorizationPage);
  }

  Future<void> _twitterLogInFinish(
      String oauthToken, String oauthVerifier) async {
    // Step 3 - Request Access Token
    final tokenCredentialsResponse = await _oauth.requestTokenCredentials(
        Credentials(oauthToken, ''), oauthVerifier);

    final result = TwitterAuthProvider.getCredential(
      authToken: tokenCredentialsResponse.credentials.token,
      authTokenSecret: tokenCredentialsResponse.credentials.tokenSecret,
    );

    Navigator.pop(context, result);
  }

  @override
  Widget build(BuildContext context) {
    return WebviewScaffold(
      appBar: AppBar(title: Text("Twitter Login")),
      url: "https://twitter.com",
    );
  }
}

然后,可以将来自此屏幕的 AuthCredential 结果传递给 FirebaseAuth.signInWithCredential.

Then, the AuthCredential result from this screen can be passed to FirebaseAuth.signInWithCredential.