Flutter OAuth认证插件oauth_chopper的使用

发布于 1周前 作者 vueper 来自 Flutter

Flutter OAuth认证插件oauth_chopper的使用

功能

oauth_chopper 插件为你的 Chopper 客户端提供了 OAuth2 认证管理功能。它结合了 Dart 团队的 oauth2 包和 Chopper,提供了一个 Chopper Authenticator 和 HeaderInterceptor 来管理 OAuth2 授权。

  • 默认情况下,它不会持久化任何凭据信息,而是使用内存存储。你可以通过提供自定义的存储实现来覆盖这一行为。
  • 目前支持以下授权类型
    • ResourceOwnerPasswordGrant(资源所有者密码授权)
    • ClientCredentialsGrant(客户端凭证授权)
    • AuthorizationCodeGrant(授权码授权)

使用方法

1. 创建 OAuthChopper 实例

首先,你需要创建一个 OAuthChopper 实例,并传入必要的参数,如 authorizationEndpointidentifiersecret

import 'package:chopper/chopper.dart';
import 'package:oauth_chopper/oauth_chopper.dart';

void main() {
  // 定义授权端点、标识符和密钥
  final authorizationEndpoint = Uri.parse('https://example.com/oauth');
  final identifier = 'your_client_id';
  final secret = 'your_client_secret';

  /// 创建 OAuthChopper 实例
  final oauthChopper = OAuthChopper(
    authorizationEndpoint: authorizationEndpoint,
    identifier: identifier,
    secret: secret,
  );
}
2. 添加 OAuthChopper 拦截器到 Chopper 客户端

接下来,将 oauthChopper.interceptor() 添加到你的 Chopper 客户端中,以便在每次请求时自动处理 OAuth2 认证。

/// 创建 Chopper 客户端并添加拦截器
final chopperClient = ChopperClient(
  baseUrl: Uri.parse('https://example.com'),
  interceptors: [
    oauthChopper.interceptor(),
  ],
);
3. 请求 OAuth 授权

根据你使用的授权类型,调用 oauthChopper.requestGrant() 方法来请求授权。以下是几种常见的授权类型的示例:

3.1 ResourceOwnerPasswordGrant(资源所有者密码授权)

适用于用户通过用户名和密码进行授权的情况。

/// 请求 ResourceOwnerPasswordGrant 授权
oauthChopper.requestGrant(
  ResourceOwnerPasswordGrant(
    username: 'your_username',
    password: 'your_password',
  ),
);
3.2 ClientCredentialsGrant(客户端凭证授权)

适用于服务器到服务器的授权,通常用于机器与机器之间的通信。

/// 请求 ClientCredentialsGrant 授权
oauthChopper.requestGrant(
  ClientCredentialsGrant(),
);
3.3 AuthorizationCodeGrant(授权码授权)

适用于用户通过浏览器重定向进行授权的情况。

/// 请求 AuthorizationCodeGrant 授权
oauthChopper.requestGrant(
  AuthorizationCodeGrant(
    tokenEndpoint: Uri.parse("https://example.com/token"),
    scopes: ["scope1", "scope2"],
    redirectUrl: Uri.parse("https://example.com/callback"),
    redirect: (url) {
      // 处理重定向 URL
      print("Redirect to: $url");
    },
    listen: (code) {
      // 处理授权码
      print("Authorization code: $code");
    },
  ),
);

持久化 OAuth2 凭据

如果你希望持久化 OAuth2 凭据信息,可以使用 flutter_secure_storage 提供的自定义存储实现。以下是一个简单的 OAuthCredentialsStorage 实现示例:

import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:oauth_chopper/oauth_chopper.dart';

const _storageKey = 'oauth_credentials';

class OAuthCredentialsStorage implements OAuthStorage {
  final FlutterSecureStorage _storage;

  const OAuthCredentialsStorage(this._storage);

  @override
  FutureOr<void> clear() async {
    await _storage.delete(key: _storageKey);
  }

  @override
  FutureOr<String?> fetchCredentials() async {
    return await _storage.read(key: _storageKey);
  }

  @override
  FutureOr<void> saveCredentials(String? credentialsJson) async {
    await _storage.write(key: _storageKey, value: credentialsJson);
  }
}

// 使用自定义存储
final oauthChopper = OAuthChopper(
  authorizationEndpoint: authorizationEndpoint,
  identifier: identifier,
  secret: secret,
  storage: OAuthCredentialsStorage(FlutterSecureStorage()),
);

完整示例代码

以下是一个完整的示例代码,展示了如何使用 oauth_chopper 插件进行 OAuth2 认证:

import 'package:chopper/chopper.dart';
import 'package:oauth_chopper/oauth_chopper.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';

void main() {
  // 定义授权端点、标识符和密钥
  final authorizationEndpoint = Uri.parse('https://example.com/oauth');
  final identifier = 'your_client_id';
  final secret = 'your_client_secret';

  // 创建自定义存储
  final storage = OAuthCredentialsStorage(FlutterSecureStorage());

  // 创建 OAuthChopper 实例
  final oauthChopper = OAuthChopper(
    authorizationEndpoint: authorizationEndpoint,
    identifier: identifier,
    secret: secret,
    storage: storage,
  );

  // 创建 Chopper 客户端并添加拦截器
  final chopperClient = ChopperClient(
    baseUrl: Uri.parse('https://example.com'),
    interceptors: [
      oauthChopper.interceptor(),
    ],
  );

  // 请求 ResourceOwnerPasswordGrant 授权
  oauthChopper.requestGrant(
    ResourceOwnerPasswordGrant(
      username: 'your_username',
      password: 'your_password',
    ),
  );

  // 请求 ClientCredentialsGrant 授权
  oauthChopper.requestGrant(
    ClientCredentialsGrant(),
  );

  // 请求 AuthorizationCodeGrant 授权
  oauthChopper.requestGrant(
    AuthorizationCodeGrant(
      tokenEndpoint: Uri.parse("https://example.com/token"),
      scopes: ["scope1", "scope2"],
      redirectUrl: Uri.parse("https://example.com/callback"),
      redirect: (url) {
        // 处理重定向 URL
        print("Redirect to: $url");
      },
      listen: (code) {
        // 处理授权码
        print("Authorization code: $code");
      },
    ),
  );
}

更多关于Flutter OAuth认证插件oauth_chopper的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter OAuth认证插件oauth_chopper的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter应用中实现OAuth认证,oauth_chopper 插件是一个很好的选择,它结合了 Chopper 网络请求库,简化了 OAuth 2.0 认证流程。以下是一个使用 oauth_chopper 插件的示例代码,展示了如何进行 OAuth 认证。

首先,确保你的 Flutter 项目中已经添加了 oauth_chopperchopper 依赖。在 pubspec.yaml 文件中添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  chopper: ^4.0.1  # 请检查最新版本号
  oauth_chopper: ^2.0.0  # 请检查最新版本号

然后,运行 flutter pub get 来获取这些依赖。

接下来,我们需要设置 Chopper 客户端和 OAuth 认证服务。以下是一个完整的示例:

import 'package:flutter/material.dart';
import 'package:chopper/chopper.dart';
import 'package:oauth_chopper/oauth_chopper.dart';

part 'auth_service.chopper.dart';

// 定义 OAuth 配置
final oauth2Config = OAuth2Configuration(
  baseUrl: 'https://api.example.com',
  clientId: 'your-client-id',
  clientSecret: 'your-client-secret', // 如果需要的话
  accessTokenEndpoint: 'https://auth.example.com/oauth/token',
  authorizeEndpoint: 'https://auth.example.com/oauth/authorize',
  scopes: ['read', 'write'],
  redirectUri: 'your-redirect-uri://callback',
);

// 定义 API 服务接口
@ChopperApi(baseUrl: 'https://api.example.com')
abstract class AuthService extends ChopperClient {
  static AuthService create() {
    final client = ChopperClient(
      baseUrl: oauth2Config.baseUrl,
      services: [
        _$AuthService(),
      ],
      converter: JsonConverter(),
      interceptors: [
        OAuth2Interceptor(oauth2Config), // 添加 OAuth2 拦截器
      ],
    );
    return _$AuthServiceImpl(client);
  }

  @Get(path: '/userinfo')
  Future<Response<UserInfo>> getUserInfo();
}

// 用户信息数据模型
class UserInfo {
  String sub;
  String name;
  String email;

  UserInfo({required this.sub, required this.name, required this.email});

  UserInfo.fromJson(Map<String, dynamic> json)
      : sub = json['sub'],
        name = json['name'],
        email = json['email'];

  Map<String, dynamic> toJson() => {
        'sub': sub,
        'name': name,
        'email': email,
      };
}

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late AuthService authService;
  UserInfo? userInfo;

  @override
  void initState() {
    super.initState();
    authService = AuthService.create();
    // 在这里启动 OAuth 流程,通常是通过一个 WebView 或系统浏览器
    // 由于示例限制,这里假设你已经有了 access token
    // 正常情况下,你需要处理重定向 URI 并提取 access token
    // 然后使用 `OAuth2Interceptor` 的 `updateToken` 方法更新 token
    // 这里我们直接模拟一个 access token
    oauth2Config.tokenStorage.saveAccessToken(
      AccessToken(
        accessToken: 'your-access-token',
        tokenType: 'Bearer',
        expiresIn: 3600,
        refreshToken: 'your-refresh-token', // 如果有的话
        scope: 'read write',
        expiresAt: DateTime.now().add(Duration(seconds: 3600)),
      ),
    );

    // 使用更新后的 token 调用 API
    fetchUserInfo();
  }

  void fetchUserInfo() async {
    try {
      final response = await authService.getUserInfo();
      if (response.isSuccessful) {
        setState(() {
          userInfo = UserInfo.fromJson(response.body!);
        });
      } else {
        print('Error fetching user info: ${response.errorMessage}');
      }
    } catch (e) {
      print('Exception: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('OAuth Chopper Example'),
        ),
        body: Center(
          child: userInfo == null
              ? CircularProgressIndicator()
              : Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Text('Name: ${userInfo!.name}'),
                    Text('Email: ${userInfo!.email}'),
                  ],
                ),
        ),
      ),
    );
  }
}

注意事项:

  1. OAuth 流程:实际应用中,你需要处理 OAuth 认证流程,通常是通过一个 WebView 或系统浏览器让用户登录并授权。在回调 URI 中提取 access token,并使用 OAuth2InterceptorupdateToken 方法更新 token。
  2. 错误处理:示例中简化了错误处理,实际应用中应增加更多的错误处理逻辑。
  3. 依赖版本:确保使用最新版本的 chopperoauth_chopper 插件。

这个示例展示了如何使用 oauth_chopper 插件在 Flutter 应用中实现 OAuth 2.0 认证,并通过 Chopper 客户端调用受保护的 API。

回到顶部