Open tomtaylor opened 6 days ago
Hello there. I'm interested in this proposal. Is there any chance we could see the implementation you have currently? That would help me ensure I understand the flow correctly.
Hey @aj-foster, sure thing.
In my our controller which implements the Ueberauth callback, we also have the following action:
@doc """
The Apple provider hits our callback URL as a cross site `POST` request.
Because we implement `Same-Site: Lax` on our cookies, this means the request
lands without any cookies. To work around this, we redirect the user to the
normal `GET` callback URL, using the action below, which passes the original
form parameters as query params. Following the redirect, the browser sends the
usual cookies with this request, and the callback can proceed as normal.
"""
def post_redirector(%Plug.Conn{} = conn, %{"provider" => provider}) do
conn
|> redirect(to: ~p"/en-gb/auth/#{provider}/callback?#{conn.body_params}")
end
The provider is defined like so:
apple:
{Ueberauth.Strategy.Apple,
[
default_scope: "name email",
request_path: "/en-gb/auth/apple",
callback_path: "/en-gb/auth/apple/callback",
callback_methods: ["POST", "GET"]
]}
And then our router is defined similar to:
scope "/en-gb", PoplarWeb do
pipe_through :minimal_browser
post "/auth/:provider/callback", OauthController, :post_redirector
end
Does that give you enough to go on?
Problem Statement
The Apple OAuth implementation is a bit odd, in that it performs a cross site form
POST
request to the callback URL, not aGET
redirection. This means that any cookies with anything other thanSame-Site: None
are not sent on the callback request. Currently the library encourages users to downgrade the security of those cookies toSame-Site: None
, but I believe there's a better solution.Solution Brainstorm
Instead of downgrading the security,
ueberauth_apple
could implement aPOST
handler action, which takes the form params and converts them to aGET
request to the callback with query params. TheGET
request will include the cookies withSame-Site: Lax/Strict
, so it will behave in the same way to any other Ueberauth callback. I've implemented something similar manually, and it works well, but I think it could be included in the library for a smoother path.