Hello everyone! I am trying to build an app that will support log in with Discord. Their docs link and link recommend sending a nonce/csrf along with the initial auth request, and then verifying said nonce/token when Discord redirects the user back to the specified redirect_uri.
I am testing this flow right now (before integrating with Discord) by doing the following:
- When the user clicks the “Login” button they are redirected to /login
/login
detects the user hasn’t logged in yet, so- they are redirected to a faked version of (what will be) the
redirect_uri
(/login?code=<CODE>
) with a hard-coded dummycode
param. This is what Discord will provide once integrated and will be exchanged for the user’s real token.
I am trying to get the nonce/csrf bit working. I changed the redirect to include a state
param that is generated by get_csrf_token()/0
(so now /login
redirects to /login?code=<CODE>&state=#{get_csrf_token()}
). But when I am handling the response I am trying to verify the CSRF with Plug.CSRFProtection.valid_state_and_csrf_token?()/2
and getting false
values. Is there a step I’m missing to get this to work?
Here’s actual code (with irrelevant parts removed for brevity):
def login(conn, %{"code" => code, "state" => state}) do
Plug.CSRFProtection.valid_state_and_csrf_token?(get_session(conn), state)
|> dbg() # logs `false` to console
end
def login(conn, _) do
redirect(conn, to: "/login?code=abcdef&state=#{get_csrf_token()}")
end