如何协调 Devise reset-password 路由与 ApiConstraints?
How to conciliate Devise reset-password route with ApiConstraints?
我正在使用 devise_token_auth 并且一切正常,直到我向路由添加 API 约束:constraints: ApiConstraint.new(version: 4, default: true)
Rails.application.routes.draw do
namespace :api do
scope module: :v4, constraints: ApiConstraint.new(version: 4, default: true) do
# Token auth routes available at /api/auth
mount_devise_token_auth_for "User", at: "auth"
end
end
end
添加这些约束会限制对路由的访问,除非请求包含正确的 headers:
class ApiConstraint
attr_reader :version
VENDOR_MIME = "application/vnd.myproject-v%d"
def initialize(version: "4", default: false)
@version, @default = version, default
end
def matches?(request)
byebug # <-- I wish there was something like request.current_path available
return @default unless request.headers.key?("accept")
request
.headers
.fetch("accept")
.include?(VENDOR_MIME % version)
end
end
我意识到这对于我们通过电子邮件收到的重置密码link是有问题的:
https://myproject.herokuapp.com/api/auth/password/edit?reset_password_token=...
...因为它不能携带任何 headers!
我可以将用户重定向到一个网页,该网页然后使用适当的 headers 进行 AJAX 调用,但我想知道是否有办法增强我的 routes.rb
或ApiConstraint
class 要在 /auth/password/edit
路线上例外?
您可以使用 request.url
、request.fullpath
、request.params
访问您需要的数据。
更重要的是,为了弄清楚在运行时哪些方法对您可用,一旦 REPL 在您放置 byebug
调试器条目的行上打开,您可以使用以下这些方法(假设你使用 pry
):
ls # display everything in the current scope
cd request # or any other variable or instance variable.
cd .. # you can navigate your code as if it was a filesystem
request.methods.grep /path/
request.methods.grep /url/
request.methods.grep /param/
# or
cd request
methods.grep /query/
OP更新
# api_constraint.rb
def initialize(version: "4", default: false, exceptions: [])
@version, @default, @exceptions = version, default, exceptions
end
def matches?(request)
return true if @exceptions.include? request.path
...
end
#routes.rb
scope module: :v4, constraints: ApiConstraint.new(version: 4, default: true, exceptions: [
"/api/auth/password/edit"
]) do
...
end
我正在使用 devise_token_auth 并且一切正常,直到我向路由添加 API 约束:constraints: ApiConstraint.new(version: 4, default: true)
Rails.application.routes.draw do
namespace :api do
scope module: :v4, constraints: ApiConstraint.new(version: 4, default: true) do
# Token auth routes available at /api/auth
mount_devise_token_auth_for "User", at: "auth"
end
end
end
添加这些约束会限制对路由的访问,除非请求包含正确的 headers:
class ApiConstraint
attr_reader :version
VENDOR_MIME = "application/vnd.myproject-v%d"
def initialize(version: "4", default: false)
@version, @default = version, default
end
def matches?(request)
byebug # <-- I wish there was something like request.current_path available
return @default unless request.headers.key?("accept")
request
.headers
.fetch("accept")
.include?(VENDOR_MIME % version)
end
end
我意识到这对于我们通过电子邮件收到的重置密码link是有问题的:
https://myproject.herokuapp.com/api/auth/password/edit?reset_password_token=...
...因为它不能携带任何 headers!
我可以将用户重定向到一个网页,该网页然后使用适当的 headers 进行 AJAX 调用,但我想知道是否有办法增强我的 routes.rb
或ApiConstraint
class 要在 /auth/password/edit
路线上例外?
您可以使用 request.url
、request.fullpath
、request.params
访问您需要的数据。
更重要的是,为了弄清楚在运行时哪些方法对您可用,一旦 REPL 在您放置 byebug
调试器条目的行上打开,您可以使用以下这些方法(假设你使用 pry
):
ls # display everything in the current scope
cd request # or any other variable or instance variable.
cd .. # you can navigate your code as if it was a filesystem
request.methods.grep /path/
request.methods.grep /url/
request.methods.grep /param/
# or
cd request
methods.grep /query/
OP更新
# api_constraint.rb
def initialize(version: "4", default: false, exceptions: [])
@version, @default, @exceptions = version, default, exceptions
end
def matches?(request)
return true if @exceptions.include? request.path
...
end
#routes.rb
scope module: :v4, constraints: ApiConstraint.new(version: 4, default: true, exceptions: [
"/api/auth/password/edit"
]) do
...
end