首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Guardian文件不让我生成JWT令牌

Guardian文件不让我生成JWT令牌
EN

Stack Overflow用户
提问于 2019-07-12 17:26:30
回答 2查看 161关注 0票数 0

我正在为我的项目使用{:guardian,"~> 1.0"}来生成一个令牌,但它给了我一个错误。

这是我的守护文件的代码

代码语言:javascript
复制
defmodule Dailyploy.Guardian do
  use Guardian, otp_app: :dailyploy

  def subject_for_token(user, _claims) do
    sub = to_string(user.id)
    {:ok, sub}
  end

  def subject_for_token(_, _) do
    {:error, :reason_for_error}
  end

  def resource_from_claims(claims) do
    id = claims["sub"]
    resource = Dailyploy.Accounts.get_user!(id)
    {:ok,  resource}
  end

  def resource_from_claims(_claims) do
    {:error, :reason_for_error}
  end
end

它向我显示了一个错误,subject_for_token。此子句无法匹配,因为第4行的前一个子句始终为matchesElixir

有人能解释一下为什么它不工作吗?

EN

回答 2

Stack Overflow用户

发布于 2019-07-12 18:01:23

编译器抱怨是因为你对subject_for_token的两个定义是相同的,它们都需要完全相同的参数。

要解决此问题,请明确表示您希望在第一个定义中接收User结构:

代码语言:javascript
复制
  def subject_for_token(%User{id: id}, _claims) do
    {:ok, to_string(id)}
  end

  def subject_for_token(_, _) do
    {:error, :reason_for_error}
  end

对于resource_from_claims也是如此;这两个函数将匹配完全相同的参数。这也是可以修复的:

代码语言:javascript
复制
  def resource_from_claims(%{"sub" => sub}) do
    resource = Dailyploy.Accounts.get_user!(sub)
    {:ok, resource}
  end

  def resource_from_claims(_claims) do
    {:error, :reason_for_error}
  end
票数 1
EN

Stack Overflow用户

发布于 2019-07-13 00:02:06

,有人能解释一下为什么它不工作吗?

调用函数时,elixir从定义中的第一个function子句开始,并尝试将函数调用中指定的参数与函数定义中的参数进行匹配。如果没有匹配,则elixir会尝试下一个函数子句。当找到匹配项时,执行相应的函数体。如果function子句都不匹配,则会出现function_clause错误。

让我们来看一个例子。如果你这样写:

代码语言:javascript
复制
def go({1, 2}, :cat) do
   IO.puts "I must have matched the function call."
end

然后,您可以像这样调用该函数:

代码语言:javascript
复制
iex(2)> A.go({1, 2}, :cat)
I must have matched the function call.
:ok

但是,如果你尝试:

代码语言:javascript
复制
ex(3)> A.go("hello", 10)
** (FunctionClauseError) no function clause matching in A.go/2    

    The following arguments were given to A.go/2:

        # 1
        "hello"

        # 2
        10

    a.ex:2: A.go/2

您会得到一个function子句错误,因为没有用于go()定义的function子句与函数调用匹配:

代码语言:javascript
复制
  function call:     A.go("hello", 10)
                            |       |
            {1,2} = "hello  |       | :cat = 10
                            V       V
  function def:    def go({1, 2}, :cat) do

go()函数调用中唯一可以与函数定义中的元组{1, 2}匹配的参数是元组{1, 2},函数调用中可以与函数定义中的原子:cat匹配的唯一参数是原子:cat

但是,函数定义中的变量可以匹配任何内容。合法变量名的例子有:xy_x_。因此,如果您这样定义go()

代码语言:javascript
复制
  def go(_x, _y) do
    IO.puts "I must have matched the function call."
  end

则两个函数调用将匹配:

代码语言:javascript
复制
iex(3)> c "a.ex"          
warning: redefining module A (current version defined in memory)
  a.ex:1
[A]

iex(4)> A.go("hello", 10)
I must have matched the function call.
:ok

iex(5)> A.go({1, 2}, :cat)
I must have matched the function call.
:ok

如果在go()定义中添加第二个function子句:

代码语言:javascript
复制
  def go(_x, _y) do
    IO.puts "I must have matched the function call."
  end
  def go(_, _) do
    IO.puts "I will never match"
  end

第一个function子句仍然会匹配任意两个参数,因此第二个function子句将永远不会执行--因此编译器会给出一个警告,相当于:

Wtf当第二个function子句永远不会匹配,因此永远不会执行时,您为什么要在第二个function子句中草草写下所有这些垃圾?!抓紧了!

例如,当你在函数定义中进行模式匹配时,事情就变得有点棘手了:

代码语言:javascript
复制
def go(%{a: val}=map, x) do

有关其工作原理,请参阅here

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57004097

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档