草庐IT

javascript - 我是否必须将 token 存储在 cookie、localstorage 或 session 中?

coder 2024-05-06 原文

我正在使用 React SPA、Express、Express-session、Passport 和 JWT。
我对存储 token 的一些不同客户端存储选项感到困惑:Cookies、Session 和 JWT/Passport。

token 是否必须存储在 cookie 中,即使我可以将它们存储在 req.sessionID 中?

许多网站使用 cookie 来存储购物车 token 。到目前为止,我已经根据 session ID 存储了购物车数据,而没有添加任何 cookie。

So when users visit my website, I will match it with their req.sessionID and then retrieve the data in the database like shopping carts and user session.



我需要存储cookies吗?我可以通过 req.sessionID 访问它以获取所需的数据。

第二个

我已使用 passport-google-oauth20 进行身份验证.我成功登录后,数据被保存到 session 中。并将其发送给客户端,我必须通过 URL 查询 ?token='sdsaxas' 发送它.

in this case I get a lot of difference of opinion. someone saved it into local storage and someone saved it into cookies by converting it to a token using JWT.


 jwt.sign(
        payload,
        keys.jwt.secretOrPrivateKey, 
        {
            expiresIn:keys.jwt.expiresIn // < i dont know what is this expired for cookies or localstorage ?
        }, (err, token) => {

            res.redirect(keys.origin.url + "?token=" + token);
        });

我确实可以使用 sessionID(没有 cookie 或 localstorage)存储与 session 相关的所有内容吗?

由于我使用 React SPA,因此只能通过执行一次或每次页面刷新并检索数据然后保存到 redux 中。

最佳答案

这个答案基于无状态方法,因此它没有讨论传统的 session 管理
你问了两个完全不同的问题:

  • 购物车 - 与业务功能更相关
  • OAuth 2 & JWT - 与安全和认证相关

  • 作为电子商务网站的用户,我希望我在上类途中从移动设备添加到购物车中的任何商品都应该在我回家后从 PC 登录网站时出现在购物车中。因此,购物车数据应保存在后端数据库中并链接到我的用户帐户。
    在使用 OAuth 2.0 进行身份验证时,JWT 访问 token 和/或刷新 token 需要存储在客户端设备中的某个位置,以便一旦用户通过提供登录凭据对自己进行身份验证,他就不需要再次提供他的凭据浏览网站。在这种情况下,浏览器本地存储、 session 存储和 cookie 都是有效的选项。但是,请注意,此处的 cookie 未链接到服务器端的任何 session 。换句话说,cookie 不存储任何 session ID。 cookie 仅用作访问 token 的存储,访问 token 随每个 http 请求传递到服务器,然后服务器使用数字签名验证 token 以确保它没有被篡改和过期。
    尽管访问和/或刷新 token 的所有三个存储选项都很流行,但如果以正确的方式使用,cookie 似乎是最安全的选项。
    为了更好地理解这一点,我建议您阅读 thisthis以及 OAuth 2.0 规范。
    2019 年 2 月 16 日更新
    我之前说过 cookie 似乎是最安全的选项。我想在这里进一步澄清这一点。
    我认为浏览器的原因localStoragesessionStorage没有为存储 auth token 提供足够的安全性如下:
  • 如果发生 XSS,恶意脚本可以轻松地从那里读取 token 并将它们发送到远程服务器。在那里,远程服务器或攻击者在冒充受害用户方面没有问题。
  • localStoragesessionStorage不跨子域共享。因此,如果我们有两个 SPA 在不同的子域上运行,我们将无法获得 SSO 功能,因为组织内的另一个应用程序无法使用一个应用程序存储的 token 。有一些解决方案使用 iframe ,但这些看起来更像是变通方法而不是好的解决方案。而当响应头 X-Frame-Options用于避免点击劫持攻击 iframe , 任何带有 iframe 的解决方案毫无疑问。

  • 但是,可以通过使用指纹(如 OWASP JWT Cheat Sheet 中所述)来减轻这些风险,而指纹又需要一个 cookie。
    指纹的想法是,生成加密强的随机字节串。然后原始字符串的 Base64 字符串将存储在 HttpOnly 中。 , Secure , SameSite带有名称前缀的 cookie __Secure- .应根据业务需求使用域和路径属性的正确值。字符串的 SHA256 哈希值也将在 JWT 的声明中传递。因此,即使 XSS 攻击将 JWT 访问 token 发送到攻击者控制的远程服务器,它也无法发送 cookie 中的原始字符串,因此服务器可以基于 cookie 的缺失拒绝请求。 cookie 是 HttpOnly XSS 脚本无法读取。
    因此,即使我们使用 localStoragesessionStorage ,我们必须使用 cookie 来确保它的安全。最重要的是,我们添加了如上所述的子域限制。
    现在,使用 cookie 存储 JWT 的唯一问题是 CSRF 攻击。由于我们使用 SameSite cookie,CSRF 得到缓解,因为跨站点请求(AJAX 或仅通过超链接)是不可能的。如果该网站在任何旧浏览器或其他不支持的不太流行的浏览器中使用 SameSite cookie,我们仍然可以通过额外使用具有加密强随机值的 CSRF cookie 来缓解 CSRF,这样每个 AJAX 请求都会读取 cookie 值并将 cookie 值添加到自定义 HTTP header 中(除了不应该这样做的 GET 和 HEAD 请求)任何状态修改)。由于CSRF由于同源策略无法读取任何内容,并且它基于利用POST,PUT和DELETE等不安全的HTTP方法,因此该CSRF cookie将减轻CSRF风险。所有现代 SPA 框架都使用这种使用 CSRF cookie 的方法。提到了 Angular 方法 here .
    此外,由于 cookie 是 httpOnlySecured , XSS 脚本无法读取。因此,XSS 也得到了缓解。
    可能还值得一提的是,通过使用适当的 content-security-policy 可以进一步减轻 XSS 和脚本注入(inject)。响应头。
    其他CSRF缓解方法
  • 状态变量(Auth0 使用它) - 客户端将生成并通过每个请求传递一个加密的强随机随机数,服务器将与其响应一起回显,允许客户端验证随机数。在 Auth0 doc 中有解释.
  • 始终检查引用 header 并仅在引用域是受信任域时才接受请求。如果引用 header 不存在或域未列入白名单,只需拒绝请求即可。使用 SSL/TLS 时通常会出现引用。登陆页面(主要是信息性的,不包含登录表单或任何安全内容)可能有点放松,并允许缺少引用 header 的请求。
  • 应在服务器中阻止 TRACE HTTP 方法,因为这可用于读取 httpOnly曲奇饼。
  • 另外,设置 header Strict-Transport-Security: max-age=; includeSubDomains 只允许安全连接,以防止任何中间人覆盖来自子域的 CSRF cookie。
  • 关于javascript - 我是否必须将 token 存储在 cookie、localstorage 或 session 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54258233/

    有关javascript - 我是否必须将 token 存储在 cookie、localstorage 或 session 中?的更多相关文章

    1. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

      我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

    2. ruby-on-rails - Rails 中的 NoMethodError::MailersController#preview undefined method `activation_token=' for nil:NilClass - 2

      似乎无法为此找到有效的答案。我正在阅读Rails教程的第10章第10.1.2节,但似乎无法使邮件程序预览正常工作。我发现处理错误的所有答案都与教程的不同部分相关,我假设我犯的错误正盯着我的脸。我已经完成并将教程中的代码复制/粘贴到相关文件中,但到目前为止,我还看不出我输入的内容与教程中的内容有什么区别。到目前为止,建议是在函数定义中添加或删除参数user,但这并没有解决问题。触发错误的url是http://localhost:3000/rails/mailers/user_mailer/account_activation.http://localhost:3000/rails/mai

    3. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

      rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

    4. ruby - Rack:如何将 URL 存储为变量? - 2

      我正在编写一个简单的静态Rack应用程序。查看下面的config.ru代码:useRack::Static,:urls=>["/elements","/img","/pages","/users","/css","/js"],:root=>"archive"map'/'dorunProc.new{|env|[200,{'Content-Type'=>'text/html','Cache-Control'=>'public,max-age=6400'},File.open('archive/splash.html',File::RDONLY)]}endmap'/pages/search.

    5. ruby-on-rails - Rails 优雅地处理超时 session ? - 2

      使用rails4,ruby2。我在rails配置中为我的cookiesession设置了30分钟的超时时间。问题是,如果我转到表单,让session超时,然后提交表单,我会收到此ActionController::InvalidAuthenticityToken错误。如何在Rails中优雅地处理这个错误?比如说,重定向到登录屏幕? 最佳答案 在您的ApplicationController:rescue_fromActionController::InvalidAuthenticityTokendoredirect_tosome_p

    6. ruby-on-rails - Rails Cookie 问题 - 2

      我在ruby​​onrails应用程序中有以下新方法:defnewifcookies[:owner].empty?cookies[:owner]=SecureRandom.hexend@movie=Movie.new@movie.owner=cookies[:owner]end基本上,每个新用户都应该获得一个代码来识别他们(尽管只是通过cookie)。因此,当用户创建电影时,创建的cookie将存储在owner字段中。所以有两个问题:使用.empty?方法,当我从浏览器中删除cookie时,返回一个undefinedmethodempty?'对于nil:NilClass`当我确实已经在

    7. ruby-on-rails - 为什么在 Rails 5.1.1 中删除了 session 存储初始化程序 - 2

      我去了这个website查看Rails5.0.0和Rails5.1.1之间的区别为什么5.1.1不再包含:config/initializers/session_store.rb?谢谢 最佳答案 这是删除它的提交:Setupdefaultsessionstoreinternally,nolongerthroughanapplicationinitializer总而言之,新应用没有该初始化器,session存储默认设置为cookie存储。即与在该初始值设定项的生成版本中指定的值相同。 关于

    8. ruby-on-rails - 使用 HTTP.get_response 检索 Facebook 访问 token 时出现 Rails EOF 错误 - 2

      我试图在我的网站上实现使用Facebook登录功能,但在尝试从Facebook取回访问token时遇到障碍。这是我的代码:ifparams[:error_reason]=="user_denied"thenflash[:error]="TologinwithFacebook,youmustclick'Allow'toletthesiteaccessyourinformation"redirect_to:loginelsifparams[:code]thentoken_uri=URI.parse("https://graph.facebook.com/oauth/access_token

    9. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

      我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

    10. ruby-on-rails - 尝试设置 Amazon 的 S3 存储桶 : 403 Forbidden error & setting permissions - 2

      我正在关注Hartl的railstutorial.org并已到达11.4.4:Imageuploadinproduction.我做了什么:注册亚马逊网络服务在AmazonIdentityandAccessManagement中,我创建了一个用户。用户创建成功。在AmazonS3中,我创建了一个新存储桶。设置新存储桶的权限:权限:本教程指示“授予上一步创建的用户读写权限”。但是,在存储桶的“权限”下,未提及新用户名。我只能在每个人、经过身份验证的用户、日志传送、我和亚马逊似乎根据我的名字+数字创建的用户名之间进行选择。我已经通过选择经过身份验证的用户并选中了上传/删除和查看权限的框(而不

    随机推荐