-
-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support authorization code flow for Google OAuth #152
Comments
@samul-1 please be more concrete in your question. Explain how your pipeline works. |
I fixed the link. This issue has little to do with how my pipeline works. Google OAuth2 authentication provides two flows:
This is not a new request. Please see this PR made on the repo this project forked from: PR, and the issue mentioned here: issue. I hope this is clearer now. I doubt this issue should've been closed to begin with, as I asked about the "authorization code flow", which is a standard term that this package claims to support, not something I made up in my comment. |
I reopened the issue and I will work on this in the near future. |
Hey all, any progress on this? |
I also needed to store the refresh_token on the backend, and manage to do it with this workaround class ConvertTokenSerializer(Serializer):
grant_type = CharField(max_length=50)
backend = CharField(max_length=200)
client_id = CharField(max_length=200)
token = CharField(max_length=5000)
refresh_token = CharField(max_length=5000) # <----- we add the refresh token to the serializer inputs
class ConvertTokenView(BaseConvertTokenView):
def post(self, request: Request, *args: Any, **kwargs: Any) -> Response:
serializer = ConvertTokenSerializer(data=request.data) # <---- we use our custom serializer
serializer.is_valid(raise_exception=True)
# Use the rest framework `.data` to fake the post body of the django request.
request._request.POST = request._request.POST.copy() # type: ignore
for key, value in serializer.validated_data.items():
request._request.POST[key] = value # type: ignore
try:
url, headers, body, status = self.create_token_response(request._request)
except InvalidClientError:
return Response(
data={"invalid_client": "Missing client type."},
status=HTTP_400_BAD_REQUEST,
)
except MissingClientIdError as ex:
return Response(
data={"invalid_request": ex.description},
status=HTTP_400_BAD_REQUEST,
)
except InvalidRequestError as ex:
return Response(
data={"invalid_request": ex.description},
status=HTTP_400_BAD_REQUEST,
)
except UnsupportedGrantTypeError:
return Response(
data={"unsupported_grant_type": "Missing grant type."},
status=HTTP_400_BAD_REQUEST,
)
except AccessDeniedError:
return Response(
{"access_denied": "The token you provided is invalid or expired."},
status=HTTP_400_BAD_REQUEST,
)
except IntegrityError as e:
if "email" in str(e) and "already exists" in str(e):
return Response(
{"error": "A user with this email already exists."},
status=HTTP_400_BAD_REQUEST,
)
else:
return Response(
{"error": "Database error."},
status=HTTP_400_BAD_REQUEST,
)
except Exception as e:
return Response(
{"error": str(e)},
status=HTTP_500_INTERNAL_SERVER_ERROR,
)
return Response(data=json_loads(body), status=status) class ServiceOAuth2(OpenIdConnectAuth):
name = "service"
...
def user_data(self, access_token: str, *args: Any, **kwargs: Any) -> UserData:
data: UserData = self.get_json(
"https://service.net/core/connect/userinfo",
headers={"Authorization": f"Bearer {access_token}"},
)
return {**data, "refresh_token": self.data.get("refresh_token")} # <---- we add the refresh token to the user data, so this is stored in DB |
Guys, you can submit a pr here so that all of us can enhance the project from your experience and problems. I would be happy to contribute. |
I have a requirement to store the access token and refresh token issued by Google when a user signs into my application in order to be able to perform requests to Google Classroom API on behalf of the user, after they've granted the relevant scopes to my app.
In order to do so, I would need the frontend application to send an authorization code, as opposed to a simple access token (which I cannot refresh on my backend) https://developers.google.com/identity/protocols/oauth2/web-server#exchange-authorization-code
However, I can see that the way the
convert-token
endpoint works, it requires a token parameter to be in the request.Is there any way to support the authorization code flow, where the request simply contains an authorization code, I exchange it on my server for an access token + refresh token from Google, store them, then create the normal in-house access token and return it to the user? The last part is the same exact flow as the normal
convert-token
endpoint, but I first need to exchange the authorization code for access + refresh token.Thank you in advance.
The text was updated successfully, but these errors were encountered: