【问题标题】:Need help configuring Django Rest API with Google Oauth and Android需要帮助使用 Google Oauth 和 Android 配置 Django Rest API
【发布时间】:2020-09-11 16:21:40
【问题描述】:

我正在尝试配置我的 django rest API 以使用 google 登录 OAuth 和 django-rest-framework-social-oauth2

我已经看到this question,但我似乎无法弄清楚他们是如何检索到 access_token 的

我到目前为止所尝试的遵循this指南:

console.developers.google.com开始了一个新项目

添加到settings.py:

SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = '2377[...].apps.googleusercontent.com'
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = '[...]'
SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE = ['email']

INSTALLED_APPS = [
    ...
    # oauth
    'oauth2_provider',
    'social_django',
    'rest_framework_social_oauth2'
]

AUTHENTICATION_BACKENDS = (
    # Google OAuth2
    'social_core.backends.google.GoogleOAuth2',

    # django-rest-framework-social-oauth2
    'rest_framework_social_oauth2.backends.DjangoOAuth2',

    # Django
    'django.contrib.auth.backends.ModelBackend',
)

但是当我尝试交换我的身份验证码时,我是从 Android 上的 Google 登录获得的

gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestServerAuthCode(Values.CLIENT_ID_WEB_APP)
            .requestEmail()
            .build();

在我的 Django Rest API 后端使用访问令牌

OkHttpClient client = new OkHttpClient();
RequestBody requestBody = new FormEncodingBuilder()
    .add("grant_type", "convert_token")
    .add("client_id", Values.CLIENT_ID_REST_APP)
    .add("client_secret", Values.CLIENT_SECRET_REST_APP)
    .add("backend", "google-oauth2")
    .add("token", idToken)
    .build();

我从服务器收到 400 HTTP 响应:

{"error":"access_denied","error_description":"您的凭据不被允许"}

我错过了什么吗?提前致谢!

【问题讨论】:

    标签: android django restful-authentication


    【解决方案1】:

    一旦从管理员中删除我的应用程序并创建一个新应用程序,我就可以使用它了。另外,我删除了除管理员用户之外的所有用户。

    在我的情况下,我在 settings.py 文件中有这些更改:

    SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = '1234565432-n9vf123456perna7o1oungbqhp6rcl.apps.googleusercontent.com'
    SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = '123456trewBNqTL_or38'
    
    
    SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE = [
        'https://www.googleapis.com/auth/userinfo.email',
        'https://www.googleapis.com/auth/userinfo.profile',
    ]
    INSTALLED_APPS = [
        ...
        # Social auth
        'oauth2_provider',
        'social_django',
        'rest_framework_social_oauth2',
    ]
    AUTHENTICATION_BACKENDS = (
        'social_core.backends.google.GoogleOAuth2',
        'rest_framework_social_oauth2.backends.DjangoOAuth2',
        'django.contrib.auth.backends.ModelBackend',
    )
    

    在 Android 方面我有:

    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        val serverClientId = getString(R.string.default_web_client_id)
            val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestIdToken(serverClientId)
                .requestServerAuthCode(serverClientId)
                .requestEmail()
                .build()
    
    
        googleSignInClient = GoogleSignIn.getClient(this, so)
    }
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
            super.onActivityResult(requestCode, resultCode, data)
            if (requestCode == RC_SIGN_IN) {
                val task = GoogleSignIn.getSignedInAccountFromIntent(data)
                try {
                    val account = task.getResult(ApiException::class.java)
                    account?.let {
                        firebaseAuthWithGoogle(it)
                    }
                } catch (e: ApiException) {
                    Log.w(TAG, "Google sign in failed", e)
                }
            }
        }
    private fun firebaseAuthWithGoogle(account: GoogleSignInAccount) {
            val credential = GoogleAuthProvider.getCredential(account.idToken, null)
            mAuth.signInWithCredential(credential)
                .addOnCompleteListener(this) { task ->
                    if (task.isSuccessful) {
                        val user = mAuth.currentUser
                        Toast.makeText(this, "Authentication Success.", Toast.LENGTH_SHORT).show()
                        getGoogleAccessToken(account.idToken, account.serverAuthCode)
                    } else {
                        Toast.makeText(this, "Authentication Failed.", Toast.LENGTH_SHORT).show()
                    }
                }
        }
    

    getGoogleAccessToken 是对 https://www.googleapis.com/oauth2/v4/token/ URL 的 Google 访问令牌的改造 API 调用。

    val call = apiInterface?.getAccessToken(
                id_token = tokenId,
                authCode = authCode,
                response_type = "Code",
                redirect_uri = "",
                grant_type = "authorization_code",
                client_id = getString(R.string.default_web_client_id),
                client_secret = getString(R.string.server_client_secret)
            )
    

    API 的响应带有访问令牌。

    data class GoogleSignInAccessTokenDataClass(
    val access_token: String,
    val expires_in: Int,
    val id_token: String,
    val token_type: String
    )
    

    【讨论】:

      猜你喜欢
      • 2012-12-04
      • 2020-07-28
      • 2011-05-24
      • 2012-06-01
      • 2013-03-17
      • 1970-01-01
      • 1970-01-01
      • 2011-07-23
      • 1970-01-01
      相关资源
      最近更新 更多