Android中集成google play 登陆来获取用户名、邮件地址、token等用户信息

本文详细介绍如何在Android应用中集成Google登录功能,包括配置项目、添加依赖、实现登录流程等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、打开主界面:

https://developers.google.com/



二、点击最右侧的所有产品

https://developers.google.com/products/



三、点击登陆和身份识别,然后选择Google Sign-In


四、选择ANDROID


五、点击GET STARTED


六、点击ADD SIGN-IN TO YOUR APP


七、将谷歌登陆集成到Android应用

将谷歌登陆集成到你的Android应用

在你将谷歌登陆集成到你的app中之前,你必须在谷歌控API的控制台对该项目进行配置。接下来描述如何将谷歌登陆集成到你的app。


前期准备

-2.3或之上,并且包含Google Play Store的手机,或者Android4.2.2或者更高的Google APIS平台的系统并且有9.8.0或之上的谷歌服务。

-最新的Android SDK版本,包括SDK工具组件。可以通过Android Studio中的Android SDK Manager来进行下载。

-项目的编译版本在2.3或以上

-谷歌服务的SDK:

 1.在Android Studio中,选择Tools>Android>SDK Manager

 2.滑动到选项列表的底部,并选择Extras>Google Repository。软件包将会被下载到你的电脑,并且在SDK的配置目录下进行安装android-sdk-folder/extras/google/google_play_services

本文是推荐的开发工具Android Studio的开发指南


获取配置文件

点击下面的按钮来获取配置文件并添加到你的项目中。

配置文件为app提供了特殊的服务。在获取之前,你必须选择一个已经存在的项目或者重新创建一个。你还必须为你的app提供包名。

在创建配置文件的时候,你也必须提供签名证书的SHA-1.查看 Authenticating Your Client(https://developers.google.com/android/guides/client-auth) 获取更多的信息。


添加谷歌服务插件

Gradle的谷歌服务插件用来解析google-services.json中的配置信息。通过在project级的build.gradle中进行配置并且app级的build.gradle文件如下:

1.在project级的build.gradle中添加以下依赖:

classpath 'com.google.gms:google-services:3.0.0'


2.在app级的build.gradle中添加如下文件:

在app级的build.gradle文件中,声明Google Play Services的依赖:

apply plugin: 'com.android.application'
    ...

    dependencies {
        compile 'com.google.android.gms:play-services-auth:9.8.0'
    }

apply plugin: 'com.google.gms.google-services'




获取服务端的OAuth 2.0的客户端ID

1.打开凭证界面(https://console.developers.google.com/apis/credentials?project=test-analytics-f14b6)

2.网页应用类型的客户端ID是你的OAuth2.0客户端ID

注:如果你没有创建新的Android客户端,你可能没有网络应用类型的客户端ID.你可以在凭证界面点击创建凭证-->OAuth客户端ID来进行创建

当创建GoogleSignInOptions对象时,传入到方法requestIdToken或requestServerAuthCode.



配置谷歌登陆和谷歌客户端请求对象

1.在Activity的onCrete方法中,配置谷歌登陆所需的用户请求。例如,配置谷歌登陆请求的客户ID和基本的文件信息,创建一个默认参数的GoogleSignInOptions对象。用GoogleSignInOptions对象来配置用的邮件地址。

// Configure sign-in to request the user's ID, email address, and basic
// profile. ID and basic profile are included in DEFAULT_SIGN_IN.
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        .requestEmail()
        .build();

注:为了使用enableAutoManage,必须继承Android Support Library下的FragmentActivity或者AppCompatActivity(FragmentActivity的子类)。你可以在Fragment中使用GgoogleApiClient;然而,该fragment的父Activity必须是FragmentActivity.如果你不能继承FragmentActivity,你必须手动管理GoogleApiClient连接的生命周期。

2.在Activityd onCreate方法中,创建要给GoogleApiClient对象来访问Google Sign-In AP和其它定义的信息。

// Build a GoogleApiClient with access to the Google Sign-In API and the
// options specified by gso.
mGoogleApiClient = new GoogleApiClient.Builder(this)
        .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
        .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
        .build();

注:为了自动化管理,activity必须继承Android Support Library包下的FragmentActivity或者AppCompatActivity(FragmentActivity的子类)。你也可以在Fragment中使用GoogleApiClient,然后,该fragment的父activity必须是FragmentActivity.如果不继承FragmentActivity,那么你必须手动管理GoogleApiClient连接的生命周期。



添加谷歌登陆按钮

1.在应用布局中添加登陆按钮

<com.google.android.gms.common.SignInButton
 android:id="@+id/sign_in_button"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content" />

2.可选的:如果你使用了默认的登陆按钮而不是由资源文件中提供的,你可以通过setSize方法来定制按钮的大小

// Set the dimensions of the sign-in button.
SignInButton signInButton = (SignInButton) findViewById(R.id.sign_in_button);
signInButton
.setSize(SignInButton.SIZE_STANDARD);
3.在Activity的onCreate方法中,注册当用户点击时登陆的按钮的点击事件:

findViewById(R.id.sign_in_button).setOnClickListener(this);


开始登陆

1.在Activity的onClick方法中,通过getSingnInIntent方法来创建一个登陆的intent来处理点击,并且通过startActivityForResult来开启intent

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.sign_in_button:
            signIn();
            break;
        // ...
    }
}

private void signIn() {
    Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
    startActivityForResult(signInIntent, RC_SIGN_IN);
}

弹出提示框让用户选择一个所要登陆的账户。

2.在方法onActivityResult中从getSignInResultFromIntent中检索登陆的结果信息

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
    if (requestCode == RC_SIGN_IN) {
        GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
        handleSignInResult(result);
    }
}

在获取到登陆的结果后,可以通过方法isSuccess来检测是否登陆成功。如果登陆成功,你可以调用方法getSignInAccount来获取登陆用户信息的GoogleSignInAccount对象,例如用户名。

private void handleSignInResult(GoogleSignInResult result) {
    Log.d(TAG, "handleSignInResult:" + result.isSuccess());
    if (result.isSuccess()) {
        // Signed in successfully, show authenticated UI.
        GoogleSignInAccount acct = result.getSignInAccount();
        mStatusTextView.setText(getString(R.string.signed_in_fmt, acct.getDisplayName()));
        updateUI(true);
    } else {
        // Signed out, show unauthenticated UI.
        updateUI(false);
    }
}
可以通过getEmail方法获取email地址,getId方法获取用户的Google ID,用getIdToken方法获取用户的ID token。如果需要通过现在登陆的用户与服务器,通过发送该ID token来进行验证。

package com.gp.download.apk;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.FragmentActivity;
import android.view.View;

import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.auth.api.signin.GoogleSignInResult;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.SignInButton;


public class MainActivity extends FragmentActivity implements GoogleApiClient.OnConnectionFailedListener, View.OnClickListener {

    private Context context;
    private String dirPath;
    private GoogleApiClient mGoogleApiClient;

    private SignInButton SignInButton;

    private int RC_SIGN_IN = 1;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = getApplicationContext();
        dirPath = context.getFilesDir().toString();

        findViewById();
        initData();
        setOnClickListener();
    }

    private void setOnClickListener() {
        SignInButton.setOnClickListener(this);
    }

    private void findViewById() {
        SignInButton = (com.google.android.gms.common.SignInButton) findViewById(R.id.sign_in_button);
    }

    private void initData() {
        // Configure sign-in to request the user's ID, email address, and basic
        // profile. ID and basic profile are included in DEFAULT_SIGN_IN.
        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail()
                .build();

        // Build a GoogleApiClient with access to the Google Sign-In API and the
        // options specified by gso.
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .enableAutoManage(this /* FragmentActivity */
                        , this /* OnConnectionFailedListener */)
                .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
                .build();
    }


    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

    @Override
    public void onClick(View view) {
        System.out.println("click 1....................");
        switch (view.getId()) {
            case R.id.sign_in_button:
                System.out.println("click 2....................");
                signIn();
                break;
        }
    }

    private void signIn() {
        System.out.println("click 3....................");
        Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
        startActivityForResult(signInIntent, RC_SIGN_IN);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        System.out.println("click 4....................");
        // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
        if (requestCode == RC_SIGN_IN) {
            System.out.println("click 5....................");
            GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
            handleSignInResult(result);
        }
    }

    private void handleSignInResult(GoogleSignInResult result) {
        System.out.println("handleSignInResult:" + result.isSuccess());
        if (result.isSuccess()) {
            // Signed in successfully, show authenticated UI.
            GoogleSignInAccount acct = result.getSignInAccount();
//            mStatusTextView.setText(getString(R.string.signed_in_fmt, acct.getDisplayName()));
//            updateUI(true);
            System.out.println("login succeed........................" + acct.getIdToken());
        } else {
            // Signed out, show unauthenticated UI.
//            updateUI(false);
            System.out.println("login failed........................");
        }
    }
}

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.gp.download.apk.MainActivity">


    <com.google.android.gms.common.SignInButton
        android:id="@+id/sign_in_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>


































注:

1、出现异常:Failed to resolve: com.google.firebase:firebase-core:9.0.0


解决方法:

点击Tools>Android>SDK Manager>Launch Standalone SDK Manager,选择Google Play services 和Google Repository,并且点击install



2.在app级的build.gradle中添加apply plugin: 'com.google.gms.google-services'后报异常

Error:Execution failed for task ':app:processDebugGoogleServices'.
> File google-services.json is missing. The Google Services Plugin cannot function without it. 
   Searched Location: 
  E:\research\gp\downloadApk\app\src\debug\google-services.json
  E:\research\gp\downloadApk\app\google-services.json


解决办法:打开网址https://developers.google.com/mobile/add?platform=android&cntapi=signin&cnturl=https:%2F%2Fdevelopers.google.com%2Fidentity%2Fsign-in%2Fandroid%2Fsign-in%3Fconfigured%3Dtrue&cntlbl=Continue%20Adding%20Sign-In然后点击下载JSON,将下载下来的json放在目录E:\research\gp\downloadApk\app下(E:\research\gp\downloadApk\app为代码su)


3.当把json放到规定目录下后报的异常:

Error:Execution failed for task ':app:processDebugGoogleServices'.
> Missing project_info object


解决办法:应该从创建该json的地方下载该文件,地址:

https://developers.google.com/mobile/add?platform=android&cntapi=signin&cnturl=https:%2F%2Fdevelopers.google.com%2Fidentity%2Fsign-in%2Fandroid%2Fsign-in%3Fconfigured%3Dtrue&cntlbl=Continue%20Adding%20Sign-In


点击choose and configure services->,然后点击ENABLE GOOGLE SIGN-IN


然后点击Generate configuration files ->


点击Continue Adding Sign-In ->


然后重新进入主页:https://developers.google.com/mobile/add?platform=android&cntapi=signin&cnturl=https:%2F%2Fdevelopers.google.com%2Fidentity%2Fsign-in%2Fandroid%2Fsign-in%3Fconfigured%3Dtrue&cntlbl=Continue%20Adding%20Sign-In


点击Choose and configure services ->


点击Generate configuration files->



点击Download gogle-services.json



4.方法handleSignInResult(GoogleSignInResult result)中result.isSuccess()返回false,一般是授权没有正确配置


解决办法:

打开API控制台界面:https://console.developers.google.com/cloud-resource-manager,如果没有项目,则先创建一个项目,如果项目已经存在,则从项目中选择一个




然后点击左上角的三条横岗图标-->API管理器-->信息中心


点击启用API,并搜索Google Play  Android Developer API ,点击该API,然后点击启用



点击在API Explorer中试用此API,然后开启Authorize requests using OAuth 2.0,勾选复选框,并点击Authorize







重新回退到信息API管理器界面https://console.developers.google.com/apis/api/androidpublisher.googleapis.com/overview?project=test-analytics-f14b6&duration=PT1H,并点击创建凭据,选择OAuth客户端ID




选择Android


启动cmd控制台,并输入命令获取签名文件的SHA1值keytool -list -v -keystore E:\research\gp\downloadApk\app\download.keystore,“ E:\research\gp\downloadApk\app\download.keystore”为文件所在的完整路径


拷贝SHA1的值,输入包名,并点击创建


然后重新点击创建凭据-->OAuth客户端ID-->网页应用-->创建




5.获取到的token为空

解决办法:

 gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
//                .requestIdToken(getString(R.string.default_web_client_id))
                .requestIdToken(getString(R.string.default_web_client_id))
                .requestEmail()
                .build();

创建GoogleSignInOptions对象时,加上requestIdToken方法
 .requestIdToken(getString(R.string.default_web_client_id))




<think>首先,用户的问题是:“我想在OAuth2中如何通过token获取用户信息 请问OAuth2 获取用户信息 通过 token 的方法”。这是一个关于OAuth2协议中如何通过访问令牌(token获取用户信息的查询。 根据系统级指令,我需要: - 使用$...$格式表示行内数学表达式(虽然这个问题可能不涉及数学,但如果有变量或代码片段,我会适当处理)。 - 独立公式用$$...$$格式(这里可能不适用)。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识,如[^1]。 - 回答结构清晰,帮助用户逐步解决问题,保证真实可靠。 用户提供了几个引用: - 引用[1]:展示了通过tokenStore读取访问令牌和用户信息的方法。 - 引用[2]:解释了OAuth2AccessToken的创建过程。 - 引用[3]:讨论了自定义Token信息和认证流程。 - 引用[4]:提到TokenRequest的使用。 用户的问题核心是“通过token获取用户信息”,所以我需要基于OAuth2协议解释如何实现这一点。 关键点: - 在OAuth2中,访问令牌(access token)用于访问受保护的资源。 - 用户信息通常存储在资源服务器上,需要通过令牌验证后获取。 - 常见的方法是使用token store来验证令牌并提取用户信息,如引用[1]所示。 步骤概述: 1. 验证令牌:确保令牌有效。 2. 提取用户信息:从令牌或相关存储中获取用户详情。 在Spring Security OAuth2中,常见实现: - 使用TokenStore(如RedisTokenStore)来读取令牌。 - 通过OAuth2Authentication对象获取用户信息。 从引用[1]: - 注入RedisTokenStore。 - 使用tokenStore.readAccessToken(token)读取令牌。 - 如果令牌有效,使用tokenStore.readAuthentication(token)获取OAuth2Authentication。 - 然后从OAuth2Authentication中提取用户详情(如OpenUserDetails)。 其他引用补充: - 引用[2]:令牌创建过程,但获取用户信息更侧重于验证。 - 引用[3]:自定义Token信息,可能涉及增强令牌。 - 引用[4]:TokenRequest用于请求令牌,不是直接获取用户信息。 所以,回答应该基于引用[1]的方法,并解释清楚。 结构清晰的回答: - 介绍OAuth2中获取用户信息的背景。 - 逐步解释方法。 - 提供代码示例(如果适用)。 - 添加引用。 - 最后生成相关问题。 生成相关问题: - 基于主题,如令牌验证、自定义用户信息、性能优化等。 最终回答框架: 1. 简要解释OAuth2令牌的作用。 2. 描述通过令牌获取用户信息的步骤。 3. 提供代码示例(参考引用[1])。 4. 添加引用标识。 5. 生成相关问题。</think>### OAuth2 中通过 Token 获取用户信息的方法 在 OAuth2 协议中,访问令牌(access token)用于授权客户端访问受保护的资源(如用户信息)。获取用户信息的关键步骤是验证令牌的有效性,并从令牌关联的认证信息中提取用户详情。以下是基于 Spring Security OAuth2 的实现方法(以 Java 为例),整个过程分为令牌验证和用户信息提取两步。 #### 步骤 1: 验证令牌的有效性 首先,需要确保提供的访问令牌是有效的。这通常通过 TokenStore(如 RedisTokenStore)来完成。TokenStore 负责存储和读取令牌信息,并检查令牌是否过期或已被撤销。 - **核心方法**:使用 `tokenStore.readAccessToken(token)` 读取令牌。如果返回非空,说明令牌有效。 - **代码示例**: ```java @Autowired private RedisTokenStore tokenStore; // 注入 TokenStore,这里以 Redis 实现为例 public boolean validateToken(String token) { OAuth2AccessToken oAuth2AccessToken = tokenStore.readAccessToken(token); return oAuth2AccessToken != null && !oAuth2AccessToken.isExpired(); } ``` 此方法会检查令牌是否存在且未过期,如果有效则返回 `true`[^1]。 #### 步骤 2: 从令牌中提取用户信息 令牌验证通过后,通过 `tokenStore.readAuthentication(token)` 获取与令牌关联的认证对象(OAuth2Authentication)。该对象包含了用户认证的详细信息。 - **核心方法**:从 OAuth2Authentication 中提取 UserDetails(用户详情对象)。 - **代码示例**: ```java public UserDetails getUserDetailsFromToken(String token) { if (validateToken(token)) { OAuth2Authentication auth2Authentication = tokenStore.readAuthentication(token); if (auth2Authentication != null) { // 获取用户主体,通常为 UserDetails 实现类 OpenUserDetails userDetails = (OpenUserDetails) auth2Authentication.getUserAuthentication().getPrincipal(); return userDetails; // 返回用户信息,如用户名、角色等 } } return null; // 令牌无效或认证信息缺失 } ``` 在上述代码中: - `auth2Authentication.getUserAuthentication()` 获取用户认证对象。 - `getPrincipal()` 返回用户主体,通常转换为自定义的 UserDetails 实现类(如 OpenUserDetails),其中包含用户 ID、用户名、权限等信息[^1]。 - 如果令牌无效,方法返回 `null`,表示无法获取用户信息。 #### 注意事项 - **令牌类型**:此方法适用于 OAuth2 的 password 模式或 authorization code 模式,其中令牌通过认证服务器生成并存储[^2]。 - **自定义用户信息**:如果需要返回额外的用户字段(如邮箱或手机号),可以在 UserDetails 实现类中添加属性,并在令牌创建时通过 TokenEnhancer 增强令牌信息[^3]。 - **性能优化**:在高并发场景下,使用 RedisTokenStore 可提升令牌读取效率,避免数据库瓶颈。 - **错误处理**:令牌无效时,应返回 HTTP 401 错误,提示客户端重新获取令牌。 通过以上步骤,您可以在资源服务器中安全地通过令牌获取用户信息。该方法基于 Spring Security OAuth2 的标准实现,确保了可靠性和安全性[^1][^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值