简体   繁体   English

保护基于令牌的身份验证系统的令牌

[英]Securing the token of a token based authentication system

I am using a token based authentication for accessing a few crude web APIs I have designed for my site. 我正在使用基于令牌的身份验证来访问我为站点设计的一些原始Web API。 At login, the username and password are posted to the login API, and it generates a token with a unique secret key, and the key is stored on the database. 登录时,用户名和密码将发布到登录API,并使用唯一的密钥生成令牌,并将密钥存储在数据库中。 At each subsequent call, the token is sent with the request and verified on the server with the secret key. 在每个后续呼叫中,令牌与请求一起发送,并在服务器上使用密钥进行验证。

I am using a web app to consume this API service and deliver a front end to the users. 我正在使用一个Web应用程序来使用此API服务并向用户提供前端。 The web application is designed using HTML/Bootstrap/JQuery and the backend is written on php. 该Web应用程序是使用HTML / Bootstrap / JQuery设计的,后端是用php编写的。

I have successfully tested my app and the token based authentication works. 我已经成功测试了我的应用程序,并且基于令牌的身份验证有效。 However, I have one concern. 但是,我有一个担忧。 I find that the user id and token are displayed directly, only using url encoding on the address bar of the browser. 我发现仅使用浏览器地址栏上的url编码即可直接显示用户ID和令牌。

http://hasconpanel.ckoysolutions.com/hasconpanel.php?inputs={%20%22username%22%20:%20%22Debopam%20Parua%22%20,%20%22uid%22%20:%20%2220170520193421DP%22%20,%20%22token%22%20:%20%22Sa2pHyooWPoI79vfvJzLlw7UO%252B2p5hOpBttkEq7LQ%252BjAGm9XEmxfhLAcnJoLbqrsXCp75%252BG1M7nEUoCgsDVbIQ%253D%253D%22%20,%20%22list_of_devices%22%20:%20[{%22device_code%22:%22b8:27:eb:f1:b3:0f%22,%22device_name%22:%22First-Pi%22}]%20}

Now, if this address is copied, or suppose the browser is made to resume the previous session, no matter who tries to access it, they get an entry. 现在,如果复制了该地址,或者假定使浏览器恢复了上一个会话,那么无论是谁尝试访问它,他们都会得到一个条目。 Especially in case of public computer centers, if anyone accesses my web app with their credentials, and forgets to logout before killing the browser, the token system seems to fail miserably. 特别是在公用计算机中心的情况下,如果有人使用其凭据访问我的Web应用程序,并且在杀死浏览器之前忘记注销,则令牌系统似乎会严重失败。 Is there anyway to secure the token like encrypting it? 无论如何,是否有像加密令牌一样保护令牌的安全? Or someway for the app to not store the parameters in case of a browser/browser-tab close or at least not display it on the address bar? 还是因为浏览器/浏览器选项卡关闭或至少不在地址栏上显示而导致应用程序不存储参数? I have thought of making a fresh token at each request, but it slows the system drastically, so I want to avoid it. 我曾考虑过在每次请求时都制作一个新令牌,但是这会大大降低系统速度,因此我想避免使用它。

Please suggest some way to solve this problem. 请提出解决此问题的方法。

Thanks in advance. 提前致谢。

Edit: Explaining how the system works now: 编辑:解释系统现在如何工作:

The api system is hosted on the main domain of a shared server, and the app is hosted in a sub-domain. api系统托管在共享服务器的主域中,而应用程序托管在子域中。 The main domain also hosts several webservices that are being called from a few raspberry pis installed at home. 主域还托管一些Web服务,这些Web服务是从家里安装的一些树莓pis调用的。

This is how it works, the login is made from the primary website and on successful login, the web app is called with a get call with the user id, the token and a list of working devices for the user. 它是这样工作的,从主要网站进行登录,成功登录后,将通过带有用户ID,令牌和用户可用设备列表的get调用来调用Web应用。 Check is provided to prevent the app page being accessed without any of these three parameters. 提供检查以防止在没有这三个参数的情况下访问应用程序页面。 On fresh load, the user gets the choice to select a device from a drop-down menu. 在新负载下,用户可以从下拉菜单中选择设备。 Now, each of these working devices can have three separate systems running. 现在,每个工作设备都可以运行三个独立的系统。 So, on selecting the device, a get call is again being made to the app, with the selected device added as a parameter along with the three previous parameters. 因此,在选择设备时,将再次对应用程序进行get调用,将所选设备作为参数与之前的三个参数一起添加。 This shows the token and the uid on the address-bar. 这在地址栏上显示令牌和uid。

Token based authentication is very standard in the web world. 基于令牌的身份验证在网络世界中非常标准。 The details vary, but what you are trying to do certainly isn't crazy. 具体细节各不相同,但是您要尝试做的当然并不疯狂。 However, your security concerns are valid, and there are a number of potential solutions: 但是,您的安全问题是有效的,并且有许多潜在的解决方案:

  1. Use HTTPS exclusively. 专门使用HTTPS。 This will protect your token from being easily readable by everyone in between the user and you. 这将保护您的令牌不被用户和您之间的每个人轻易读取。 Actually, do this regardless of anything else. 实际上,不管其他任何事情,都应这样做。 HTTPS should be considered the default for security purposes these days: just pretend that HTTP is deprecated. 出于安全性考虑,如今应将HTTPS视为默认值:假装不建议使用HTTP。
  2. Move the token into the header of the request instead of the URL. 将令牌移到请求的标头而不是URL。 As long as you are using HTTPS this doesn't actually change anything from a security standpoint, but it is fairly standard for the industry. 从安全的角度来看,只要您使用HTTPS,这实际上并不会改变任何东西,但是对于业界来说,这是相当标准的。 It will also keep the token out of the browser history. 它还会将令牌保留在浏览器历史记录之外。

It is strange that you have a URL showing up in the browser address bar. 奇怪的是,浏览器地址栏中显示了一个URL。 I would expect a client-side application to make requests exclusively via ajax, which means there should't ever be anything in the address bar. 我希望客户端应用程序专门通过ajax发出请求,这意味着地址栏中永远不会有任何内容。 You might need to clarify more on how exactly this application is working. 您可能需要详细说明此应用程序的工作方式。 I suspect you need to refactor so that none of your application URLs ever end up in the address bar, and instead operate via AJAX requests exclusively. 我怀疑您需要进行重构,以使您的应用程序URL都不会最终出现在地址栏中,而是仅通过AJAX请求进行操作。

Still, HTTPS is the most important part. HTTPS仍然是最重要的部分。 Your entire transaction after DNS lookup will be transmitted securely, so the token cannot be stolen by a man-in-the-middle. DNS查找后,您的整个交易将安全地传输,因此中间人不能窃取令牌。 This is the most important step you have to take to secure it. 这是确保安全的最重要步骤。 If you don't use HTTPS, you might as well broadcast it to the world. 如果您不使用HTTPS,则最好将其广播给全世界。 Of course, if you are making non-ajax requests to a URL with the token in the query parameters then the token will be visible in the browser's address bar and history. 当然,如果您使用查询参数中的令牌对URL进行非ajax请求,则该令牌将在浏览器的地址栏和历史记录中可见。 Again, avoid that by using ajax requests only and put the cookie in the header. 同样,通过仅使用ajax请求来避免这种情况,并将cookie放在标题中。

Once you have HTTPS in place with ajax-only requests, the chances of having a token stolen are much smaller. 将HTTPS与仅ajax请求一起使用后,令牌被盗的机会就会大大减少。 Still, it can happen (in particular via an XSS attack), so become familiar with the principle of "defense in depth". 尽管如此,它仍然可能发生(尤其是通过XSS攻击),因此请熟悉“纵深防御”的原理。 Also, there are steps you can take to try to detect a stolen token an invalidate it. 此外,您可以采取一些步骤来尝试检测出被盗的令牌并使该令牌无效。 Things like: 像:

  1. Invalidate a token (for the user to log back in) if the IP Address changes (although this can impact mobile users, which probably isn't desirable) 如果IP地址更改,则使令牌无效(供用户重新登录)(尽管这可能会影响移动用户,这可能是不希望的)
  2. Invalidate a token if the user agent changes (although that can be spoofed) 如果用户代理更改,则使令牌无效(尽管可以欺骗)
  3. Enforce a server-side maximum session length 强制服务器端最大会话长度
  4. Make sure and require the user to re-authenticate if they want to change email/password. 确保并要求用户重新验证是否要更改电子邮件/密码。

Those are just a few suggestions off the top of my head. 这些只是我脑海中的一些建议。 Again though, this is a pretty standard problem, so google will be your friend. 同样,这是一个非常标准的问题,因此google将是您的朋友。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM