In phoenix, How can update global conn?

Hi, guys! I have a requestion about phoenix.

 defp gen_code(conn) do
    code = "#{:rand.uniform(9)}#{:rand.uniform(9)}#{:rand.uniform(9)}#{:rand.uniform(9)}"
    Logger.info("sms code: #{code}")
   
   # Change conn in here
    conn |> put_session(:sms_code, code)
    conn |> put_session(:sms_code_created_at, Core.Ecto.Type.CSTDateTime.now())

    code
 end

I want to get the new conn value below, but i can’t use render to change conn.
“gen_code” just handle the sms code and don’t handle any request and render. “gen_code” is put sms code to session, but can’t update global conn value. As a result, I can’t get SMS code in the create below.
How can I do ?

def create(conn, %{"user_profile" => user_profile}) do
    user = current_user(conn)
    if validate_sms_code(conn, user_profile["code"]) do
      case UserProfiles.create_user_profile(Map.merge(user_profile, %{"user_id" => user.id})) do
        {:ok, profile} ->
          send_format(conn, profile)

        {:error, changeset} ->
          send_format(conn, changeset)
      end
    else
      conn
      |> json(%{ error_str: "验证码错误", request_state: 1 })
    end
  end

…deleted…

:wave:

“gen_code” just handle the sms code and don’t handle any request and render.

Then make it do just that and not bother itself with conns:

defp gen_code do
  "#{:rand.uniform(9)}#{:rand.uniform(9)}#{:rand.uniform(9)}#{:rand.uniform(9)}"
end

And in some other function where you actually handle the connection:

code = gen_code()
Logger.info("sms code: #{code}")

conn
|> put_session(:sms_code, code) # note that the client can read it unless you encrypt the code
|> put_session(:sms_code_created_at, Core.Ecto.Type.CSTDateTime.now())

As a result, I can’t get SMS code in the create below.

I don’t see any reference to gen_code there …

Thanks, The request calling gen_code is not the same as def create, and I don’t think it will change the conn globally.

After to invoke send_resp() can update conn globally

  # def  send_sms 
  sms_code = gen_code(conn)
  case Leopard.Sms.send_sms(mobile, sms_code, user.id, ip_address) do
    {:ok, message} ->
      conn
      |> put_session(:sms_code, sms_code)
      |> put_resp_content_type("application/json")
      |> send_resp(201, "发送成功")

    {:error, changeset} ->
      conn
      |> send_resp(400, "#{inspect(changeset)}")
  end

You can not change one requests conn from another. If you need to transfer/persist data between requests, you need to use sessions and/or a database.

3 Likes

Thanks, I think I get it.

# A request 
def a(conn) do
    conn
    |> assign(:test_assign, "update assigns")
    |> put_session(:test_session, "update session")
    |> send_resp()
end 

And i try result.

# B request 
def b(conn) do
   get_session(conn, :test_session) # get  "update session"
   conn.assigns[:test_assign] # get nil
end