Open hawkyre opened 5 months ago
Great question. ❓ ❤️
The quick answer is yes. 👍
But we only tend to use it with Phoenix
so we haven't written an example without it. 🙃
Please confirm your Elixir
App has access to the required environment variable. 🔑
Yes, it does. The request is done successfully and I've compared the payload and it seems to be the same in both the phoenix and the bare elixir, but the phoenix one does return the proper profile data while the elixir can't exchange the user code for the token. Could it be the JSON parsing somehow being different? I'm also using HTTPoison.
Btw, if it's any helpful, I was testing yesterday and even though the variables were being added as I could see in the request, I modified the module code to have the client id and secret be static and that instead throws a redirect_uri_mismatch even though the redirect uri is added to the GC project.
I also wrote a different function with the same structure as the module and this one does throw the redirect_uri_mismatch as well. Here's the code:
def get_token(code) do
# Build the request body
body =
%{
client_id: "raw client id",
client_secret: "raw secret",
redirect_uri: "http://localhost:4000/auth/google/callback",
grant_type: "authorization_code",
code: code
}
|> Jason.encode!()
headers = []
# Make the HTTP POST request
case HTTPoison.post(@google_token_url, body, headers) do
{:ok, %HTTPoison.Response{status_code: 200, body: response_body}} ->
# Handle the response, typically converting JSON to an internal format
case Jason.decode(response_body) do
{:ok, decoded} -> {:ok, decoded}
{:error, reason} -> {:error, reason}
end
{:ok, %HTTPoison.Response{status_code: status} = res} ->
IO.inspect(res)
{:error, "Failed to retrieve token, status code: #{status}"}
{:error, reason} ->
{:error, reason}
end
end
Here are the response's request objects in both projects, copy pasted straight from the raw response (I'm pretty sure they are the same):
Bare elixir:
request: %HTTPoison.Request{
method: :post,
url: "https://oauth2.googleapis.com/token",
headers: [],
body: "{\"code\":\"code\",\"client_id\":\"client-id\",\"client_secret\":\"client-secret\",\"grant_type\":\"authorization_code\",\"redirect_uri\":\"http://localhost:4000/auth/google/callback\"}",
params: %{},
options: []
}
Phoenix
request: %HTTPoison.Request{
method: :post,
url: "https://oauth2.googleapis.com/token",
headers: [],
body: "{\"code\":\"code\",\"client_id\":\"client-id\",\"client_secret\":\"client-secret\",\"redirect_uri\":\"http://localhost:4000/auth/google/callback\",\"grant_type\":\"authorization_code\"}",
params: %{},
options: []
}
I can also provide how I'm treating the code in the Next.js frontend (I'm using a popup instead of a redirect):
const googleLogin = useGoogleLogin({
flow: 'auth-code',
redirect_uri: `${process.env.NEXT_PUBLIC_SERVER_URL}/auth/google/callback`,
ux_mode: 'popup',
onSuccess: async (codeResponse) => {
console.log(codeResponse);
const tokens = await getAxiosInstance().post(
`${process.env.NEXT_PUBLIC_SERVER_URL}/auth/google/callback`,
{
code: codeResponse.code,
}
);
console.log(tokens);
},
onError: (errorResponse) => console.log(errorResponse),
});
I'm trying to use this in a project without Phoenix and, with the same exact credentials, it will work on the Phoenix project but not on the Elixir one. It keeps throwing the "invalid_client" and "The OAuth client was not found." error after I request the token. I am running the server and client separately.
Here's the code:
Am I doing something wrong? This is the only relevant code to the project, and it is throwing after ElixirAuthGoogle.get_token/2