草庐IT

rest - 当前端和 API 都在同一个 Go 服务器上时,如何保护来自 CSRF 的 REST API?

coder 2023-06-29 原文

我正在开发一个用 Go 创建的网站。

可以通过网络(通过 golang 模板生成的服务器端页面)和 REST API(对于希望集成自己的软件的外部用户)进行访问。 Go 服务器处理这两种类型的请求,当调用发送到子路径“my-url-root/api”时,使用一个子路由器处理 API。

  • 网页使用安全 cookie
  • API 是无状态的:没有 cookie(每个 API 方法必须在 header 通过专用登录方法获得的身份验证 token )

我成功地应用了 gorilla/csrf 来保护网页免受 csrf 攻击,但是这种修改(在我上线之前必不可少)现在导致 API 出现问题。

我的问题 实现 CSRF 后,发送到 api URL 的所有 GET 请求都按预期工作,但发送的任何其他请求(例如,通过我的 REST api 向方法添加内容的 POST)生成一个 html 响应,通常声明“禁止 - 无效的 csrf token ”。

我是否缺少一种直接的方法?我搜索了答案,但没有一个适用于 api 由同一台服务器提供服务且大多数情况下它是无状态的情况。 我是否应该看看我是否可以为子路由器“禁用” gorilla csrf 保护(尽管我什至不知道这是否可能以及是否安全......)?

感谢您的帮助。

最佳答案

好的,所以我尝试应用上面的建议,并找到了解决问题的方法。

我通过在有和没有 csrf 保护的情况下检查我的 url 和子 url 的 web 和 api 调用来测试它是否有效。

只是对我之前的评论的澄清。更准确地说,我创建 Submux 的顺序并不重要,但当然,当我写下处理每条路径的行时,我遵循了正确的顺序。

所以,顺序很重要。

这就是我所做的(只是一些代码)。

我使用 goji 作为路由器,使用 gorilla/csrf 作为 csrf 保护。

注意:我没有包括我的所有代码,只包括最重要的部分来描述我所做的事情。

1) 我创建了一个多路复用器

mux := goji.NewMux()

2) 因为我的 API 是在 url "/api"和相关子 url 下提供的,所以我为 api 创建了一个 Submux

apiMux := goji.SubMux()

3) 我将匹配路径“/api”和“/api*”的页面分配给这个subMux

请注意,我没有包含任何 csrf 保护

mux.Handle(pat.New("/api/*"), apiMux)

mux.Handle(pat.New("/api"), apiMux)

4) 我为我网站的网页创建了一个 Submux

webMux := goji.SubMux()

5) 我将匹配路径“/”和“/*”的页面分配给这个subMux

请注意,在我的代码中,我链接了用于 csrf 保护的中间件

mux.Handle(pat.New("/"), csrf.Protect(csrfKey, csrf.Secure(true))(webMux))
mux.Handle(pat.New("/*"), csrf.Protect(csrfKey, csrf.Secure(true))(webMux))

6) 为了我的利益,我创建了其他 SubMux 来处理其他路径,例如“/users”、“/users/1”、“/users/addform”。 这一步很重要:我将这个“userMux”分配给了 webMux,而不是在步骤 1 中创建的主 mux。

这样就继承了csrf保护。示例:

usersMux := goji.SubMux()

webMux.Handle(pat.New("/users/*"), usersMux)

webMux.Handle(pat.New("/users"), usersMux)

简而言之,这就是我的问题的解决方案:

I) 我将此“apiMux”分配给在步骤 1 中创建的主多路复用器。

我没有将它分配给任何其他 mux。我没有将它分配给处理根 url“/”和“/*”的 webMux

II) 顺序很重要,所以我实现了 API url 的代码,然后是 web url 的代码

希望对你有所帮助。最重要的是,我希望解释清楚......(如果不是让我知道的话)。 谢谢你给我指明了正确的方向

关于rest - 当前端和 API 都在同一个 Go 服务器上时,如何保护来自 CSRF 的 REST API?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52889452/

有关rest - 当前端和 API 都在同一个 Go 服务器上时,如何保护来自 CSRF 的 REST API?的更多相关文章

  1. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  2. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  3. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  4. ruby-on-rails - ActionController::RoutingError: 未初始化常量 Api::V1::ApiController - 2

    我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc

  5. ruby-on-rails - 在 Rails 中调试生产服务器 - 2

    您如何在Rails中的实时服务器上进行有效调试,无论是在测试版/生产服务器上?我试过直接在服务器上修改文件,然后重启应用,但是修改好像没有生效,或者需要很长时间(缓存?)我也试过在本地做“脚本/服务器生产”,但是那很慢另一种选择是编码和部署,但效率很低。有人对他们如何有效地做到这一点有任何见解吗? 最佳答案 我会回答你的问题,即使我不同意这种热修补服务器代码的方式:)首先,你真的确定你已经重启了服务器吗?您可以通过跟踪日志文件来检查它。您更改的代码显示的View可能会被缓存。缓存页面位于tmp/cache文件夹下。您可以尝试手动删除

  6. ruby - Rails 关联 - 同一个类的多个 has_one 关系 - 2

    我的问题的一个例子是体育游戏。一场体育比赛有两支球队,一支主队和一支客队。我的事件记录模型如下:classTeam"Team"has_one:away_team,:class_name=>"Team"end我希望能够通过游戏访问一个团队,例如:Game.find(1).home_team但我收到一个单元化常量错误:Game::team。谁能告诉我我做错了什么?谢谢, 最佳答案 如果Gamehas_one:team那么Rails假设您的teams表有一个game_id列。不过,您想要的是games表有一个team_id列,在这种情况下

  7. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  8. ruby-on-rails - Mandrill API 模板 - 2

    我正在使用Mandrill的RubyAPIGem并使用以下简单的测试模板:testastic按照Heroku指南中的示例,我有以下Ruby代码:require'mandrill'm=Mandrill::API.newrendered=m.templates.render'test-template',[{:header=>'someheadertext',:main_section=>'Themaincontentblock',:footer=>'asdf'}]mail(:to=>"JaysonLane",:subject=>"TestEmail")do|format|format.h

  9. ruby-on-rails - 在 Ruby (on Rails) 中使用 imgur API 获取图像 - 2

    我正在尝试使用Ruby2.0.0和Rails4.0.0提供的API从imgur中提取图像。我已尝试按照Ruby2.0.0文档中列出的各种方式构建http请求,但均无济于事。代码如下:require'net/http'require'net/https'defimgurheaders={"Authorization"=>"Client-ID"+my_client_id}path="/3/gallery/image/#{img_id}.json"uri=URI("https://api.imgur.com"+path)request,data=Net::HTTP::Get.new(path

  10. ruby - 如何找到调用当前方法的方法 - 2

    如何找到调用此方法的位置?defto_xml(options={})binding.pryoptions=options.to_hifoptions&&options.respond_to?(:to_h)serializable_hash(options).to_xml(options)end 最佳答案 键入caller。这将返回当前调用堆栈。文档:Kernel#caller.例子[0]%rspecspec10/16|===================================================62=====

随机推荐