问题
I'm trying to configure my django rest API to authenticate using google sign in OAuth and django-rest-framework-social-oauth2
I've already seen this question but I can't seem to figure out how they retrieved the access_token
What I have tried this far following this guide:
Started a new project in console.developers.google.com
Added to 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',
)
But when I try to exchange my Auth Code, which I got from Google Sign In on Android
gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestServerAuthCode(Values.CLIENT_ID_WEB_APP)
.requestEmail()
.build();
for an access token in my Django Rest API backend using
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();
I get a 400 HTTP response from server:
{"error":"access_denied","error_description":"Your credentials aren't allowed"}
Am I missing something? Thanks in advance!
回答1:
I got it working once deleted my Application from admin and creating a new one. Also, I deleted all users apart from the admin user.
In my case I have these changes in settings.py file:
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',
)
On the Android side I have:
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 is Retrofit API call for the google access token to https://www.googleapis.com/oauth2/v4/token/ URL.
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)
)
The response for the API is with the access token.
data class GoogleSignInAccessTokenDataClass(
val access_token: String,
val expires_in: Int,
val id_token: String,
val token_type: String
)
来源:https://stackoverflow.com/questions/61995469/need-help-configuring-django-rest-api-with-google-oauth-and-android