NoD*_*ame 35 elixir phoenix-framework
我需要能够生成随机url安全字符串,以便我可以在链接中使用它们(比如发送到用户电子邮件的激活链接),那么我该如何生成呢?有没有办法只使用Elixir或我必须使用一些库?
Gja*_*don 52
您可以做的是生成Base64编码的字符串以用作确认令牌.然后,此确认令牌将保存到您的数据库,并作为参数传递给激活链接.您的激活网址如下所示:
activation_url(MyApp.Endpoint, :confirm, confirm_id: confirm_id)
Run Code Online (Sandbox Code Playgroud)
上面的url helper假定你在该控制器中有一个MyApp.ActivationController
和一个confirm/2
动作.要生成confirm_id
,您可以这样做:
def random_string(length) do
:crypto.strong_rand_bytes(length) |> Base.url_encode64 |> binary_part(0, length)
end
# random_string(64)
Run Code Online (Sandbox Code Playgroud)
在你的MyApp.ActivationController.confirm/2
,你可以有代码:
def confirm(conn, %{"confirm_id" => confirm_id}) do
user = Repo.get_by(User, confirm_id: confirm_id)
User.confirm(user)
conn
|> put_flash(:info, "Account confirmed!")
|> redirect(to: "/")
end
Run Code Online (Sandbox Code Playgroud)
希望有所帮助!
Nat*_*ong 10
您可以轻松定义模块来执行此操作.在此示例中,@chars
确定生成的字符串中显示的字符.
defmodule StringGenerator do
@chars "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |> String.split("")
def string_of_length(length) do
Enum.reduce((1..length), [], fn (_i, acc) ->
[Enum.random(@chars) | acc]
end) |> Enum.join("")
end
end
StringGenerator.string_of_length(3) # => "YCZ"
Run Code Online (Sandbox Code Playgroud)
正如@JimGray 的评论中所指出的,您的规范实际上应该是您想要由随机 URL 安全字符串表示的熵量。类似于“我需要 N 位”的内容,因为有人告诉您使用 N 位,或者“我想避免在 N 个字符串中重复,并且我可以接受 n 中 1 的冲突风险”。无论哪种方式,它都直接与熵有关,而只是间接与字符串长度有关。
例如,请确保如果您使用像 @Gjaldon' answer 这样的解决方案,即使使用了 512 位随机性,您也理解,生成的实际字符串的熵量random_string(64)
为 320 位。这是否足够当然取决于您的场景,如上所述,最好将其表达为,例如,“我需要一百万个字符串,并且重复风险不超过万亿分之一”,在这种情况下,320 位是严重矫枉过正,因为你只需要 79。
如果您想要更多地控制和理解生成随机字符串,请查看EntropyString。使用该库,您可以执行以下操作以获取具有 256 位熵的字符串:
iex> defmodule Id, do: use EntropyString, charset: charset64
iex> Id.token
"ziKYK7t5LzVYn5XiJ_jYh30KxCCsLorRXqLwwEnZYHJ"
Run Code Online (Sandbox Code Playgroud)
或者,如果您意识到一百万个字符串的重复风险为万亿分之一就足够了,您可以像这样设置您的 Id 代:
iex> defmodule Id do
...> use EntropyString, charset: charset64
...> @bits entropy_bits(1.0e6, 1.0e12)
...> def random, do: Id.random_string(@bits)
...> end
iex> Id.random
"FhlGVXOaXV9f3f"
Run Code Online (Sandbox Code Playgroud)
无论哪种方式,控制和理解都是很好的东西。