使用 laravel-socialite 后端登录用户通过社交帐户进行 flutter

Ham*_*gni 7 laravel laravel-socialite flutter

我正在开发一个 flutter 应用程序,我想实现社交登录(Google 和 Facebook)。

\n

我的 API 是用 Laravel 实现的,并使用 Laravel-socialite 来验证用户身份,有后端、Web 前端(使用 VueJs),现在我正在使用 flutter 开发移动应用程序。

\n

Web 应用程序运行良好(使用vue-social-auth包)。

\n

到目前为止我所做的:

\n
    \n
  1. 使用 flutter_google_sign_in 处理 flutter 应用程序上的身份验证。
  2. \n
  3. 配置了该包,我可以通过该包成功获取用户信息。
  4. \n
\n

我面临的问题:

\n

我似乎没有开始工作是将刚刚登录的用户发送到后端,以提供应用程序内的用户体验。

\n

这是vue-social-auth包提供的内容以及我发送到后端的内容,该后端工作正常:

\n
{code: "4/0AY0e-g442SMxdtLb_MVdQ63u1ydp48bbCRQco5Azoyf3y1rvYybDabyZGOvwAs7ZFJDQHA", scope: "email+profile+openid+https://www.googleapis.com/au\xe2\x80\xa6le+https://www.googleapis.com/auth/userinfo.email", authuser: "0", prompt: "consent"}\n
Run Code Online (Sandbox Code Playgroud)\n

这就是flutter_google_sign_in给出的(除了用户个人资料数据之外):

\n
idToken: "",\naccessToken: "",\nserverAuthCode: "", \n
Run Code Online (Sandbox Code Playgroud)\n

serverAuthCode 始终为null

\n

我怎样才能使用相同的API逻辑,通过社交帐户登录flutter上的用户?

\n

谢谢。

\n

Sam*_*ten 9

显然,除了 Firebase/某些云 API 后端服务之外,谷歌登录不适用于 flutter。我使用本地 Laravel API 进行用户身份验证,因此添加 google 登录功能需要设置 firebase 帐户/配置文件,下载 googleservices.json 文件并将其添加到 flutter 项目,如 google_sign_in 包安装手册中所述。您还需要导入 firebase-auth 包

Flutter 代码(我使用 flutter 模块化模式,但如果您明白上面 Hamza Mogni 所解释的想法,则同样适用于 Bloc/Provider)

import 'package:google_sign_in/google_sign_in.dart';
 import 'package:firebase_auth/firebase_auth.dart';

  final GoogleSignIn _googleSignIn = GoogleSignIn();
  final FirebaseAuth _auth = FirebaseAuth.instance;

  Future<LoginResponseModel> googleLoginResponse() async {
    
    String url = env['API_BASE_URL'] + '/api/auth/google';

    //click on google sign in. Get accessToken from google through googlesignin 
     plugin.
    //Send accessToken to socialite in backend to request/create user data

    GoogleSignInAccount googleSignInAccount = await _googleSignIn.signIn();
    if (googleSignInAccount == null) {
      print('Google Signin ERROR! googleAccount: null!');
      return null;
    }
    GoogleSignInAuthentication googleSignInAuthentication =
        await googleSignInAccount.authentication;
    
   //this is user access token from google that is retrieved with the plugin
    print("User Access Token: ${googleSignInAuthentication.accessToken}");
    String accessToken = googleSignInAuthentication.accessToken;
    
    //make http request to the laravel backend 
    final response =
        await http.post(
                  url,
                  body: json.encode({"token": accessToken}),
                  headers: {"Content-Type": "application/json"});
    if (response.statusCode == 200 || response.statusCode == 422) {
      return LoginResponseModel.fromJson(
        json.decode(response.body), // {'message':'Google signin successful'}
      );
    } else {
      throw Exception('Failed to load data!');
    }
  }
Run Code Online (Sandbox Code Playgroud)

对于注销功能,您需要注销 firebase 和 google 帐户实例,否则在后续登录尝试中您将始终通过第一个已知/使用的 google 帐户登录。

Future<LogoutResponseModel> logout() async {
    try {
      await _auth.signOut();
      await _googleSignIn.disconnect();
    } catch (e) {
      print('Failed to sign out ' + e.toString());
    }
    //api route to destroy sanctum token. santum token is added as authorization header
    var url = env['API_BASE_URL'] + "/api/logout";
    final response =
        await http.post(Uri.tryParse(url), headers: {'Bearer ' $sanctumtoken});
    if (response.statusCode == 200 || response.statusCode == 422) {
      return LogoutResponseModel.fromJson(
        json.decode(response.body),
      );
    } else {
      throw Exception('Failed to load data!');
    }
  }
Run Code Online (Sandbox Code Playgroud)

Laravel 代码(到控制器方法的路由是 api/auth/google,方法期望从 flutter 应用程序接收 google 访问令牌)

public function requestTokenGoogle(Request $request) {
        // Getting the user from socialite using token from google
        $user = Socialite::driver('google')->stateless()->userFromToken($request->token);

        // Getting or creating user from db
        $userFromDb = User::firstOrCreate(
            ['email' => $user->getEmail()],
            [
                'email_verified_at' => now(),
                'first_name' => $user->offsetGet('given_name'),
                'last_name' => $user->offsetGet('family_name'),
                'avatar' => $user->getAvatar(),
            ]
        );

        // Returning response
        $token = $userFromDb->createToken('Laravel Sanctum Client')->plainTextToken;
        $response = ['token' => $token, 'message' => 'Google Login/Signup Successful'];
        return response($response, 200);
    }
Run Code Online (Sandbox Code Playgroud)


Ham*_*gni 6

我已经解决了这个问题,经过一番挖掘,我发现Laravel-Socialite具有使用内置令牌登录用户的功能:

引用Socialite文档:

如果您已经拥有用户的有效访问令牌,则可以使用 Socialite 的 userFromToken 方法检索其详细信息。