简体   繁体   English

如何使用Cordova保护SPA和移动应用程序的REST API

[英]How to secure REST API for SPA and Mobile App using Cordova

I've done a lot of research on "best practices" surrounding this and have read blog post after blog post, SO question after SO question, and OWASP article after OWASP article. 我已经对围绕这个的“最佳实践”进行了大量的研究,并在博客文章之后阅读了博客文章,在SO问题之后阅读了SO问题,在OWASP文章之后阅读了OWASP文章。 I've arrived at a few clear answers but some unknowns. 我已经得到了一些明确的答案,但有些未知数。

First, the "Do's": 首先,“做”:

  1. Use JWT for authorizing users on my REST API [1] [2] 使用JWT在我的REST API上授权用户[1] [2]
  2. Store the JWT in a HTTPOnly/Secure cookie and build in CSRF protection. 将JWT存储在HTTPOnly / Secure cookie中并构建CSRF保护。 Do NOT store in HTML5 local storage [3] [4] [5] (Actually, this point is debatable, is it easier to protect against XSS or CSRF? [6] ) 不要存储在HTML5本地存储[3] [4] [5]中 (实际上,这一点值得商榷,是否更容易防范XSS或CSRF? [6]
  3. Verify the signing method of the JWT [7] 验证JWT的签名方法[7]

Now I started with the assumption that having a SPA (built with Angular) and using HTML5 sessionStorage would be secure enough for short-lived tokens, but there is a point to be made that XSS attacks can happen from a "bad actor" originating in the one of many libraries loaded in from a CDN. 现在我开始假设拥有一个SPA(使用Angular构建)并使用HTML5 sessionStorage对于短期令牌来说足够安全,但有一点可以说XSS攻击可能来自一个源自“坏角色”的“坏角色”从CDN加载的许多库之一。

For my specific use case, I do not plan on having long-lived tokens - expiration after 10 minutes of non-use but I'm still figuring out if I want to track expiration by session or use refresh tokens - StormPath recommends the former (no longer stateless?) but I believe big players using JWTs use refresh tokens (Google uses them but states you need to store them in secure, long-term storage which means HTML5 localStorage is again, out of the question). 对于我的特定用例,我不计划使用长期令牌 - 在不使用10分钟后过期但我仍然想知道我是否要通过会话跟踪到期或使用刷新令牌 - StormPath推荐前者(不再是无国籍?)但我相信使用JWT的大玩家使用刷新令牌(谷歌使用它们但声明你需要将它们存储在安全的长期存储中,这意味着HTML5 localStorage再次出现问题)。

I would like to make it so my users don't have to log back in if they refresh the page (hence the need to store the token on the client side). 我想这样做,这样我的用户如果刷新页面就不必重新登录(因此需要在客户端存储令牌)。 I would also like to use my SPA as a "mobile app" with the help of Cordova. 我还希望在Cordova的帮助下将我的SPA用作“移动应用程序”。 The obvious pitfall here is that if I use cookies, there is no baked-in cookie support/storage with Cordova and I'm urged to switch to HTML5 local storage instead. 这里显而易见的缺陷是,如果我使用cookie,Cordova没有带烘焙的cookie支持/存储,我应该转而使用HTML5本地存储。 Since on mobile I don't really need to worry about refreshing pages, I can just let my token live in memory and expire with the strategy I settle on. 因为在移动设备上我并不需要担心刷新页面,所以我可以让我的令牌存在于内存中并使用我所确定的策略到期。

If I take this approach, cookie-based JWT on Desktop, "Bearer" headers on mobile, I now need an authentication end-point that will give tokens two different ways, and when I authorize on the REST API side, I need to support both cookie-based JWTs (with CSRF) and header based JWT verification. 如果我采用这种方法,桌面上基于cookie的JWT,移动设备上的“Bearer”标头,我现在需要一个认证端点,它将以两种不同的方式给予令牌,当我在REST API端授权时,我需要支持基于cookie的JWT(带有CSRF)和基于头的JWT验证。 This complication has me worried as I don't know if I can accurately foresee security implications here. 这种复杂情况令我担心,因为我不知道我是否能准确预见到这里的安全隐患。

To summarize the barrage of thoughts above: 总结一下上面的一系列想法:

  • Create an authentication handler that would hand out tokens via HttpOnly/Secure cookies to desktop, and by payload for mobile. 创建一个身份验证处理程序,通过HttpOnly / Secure cookie将令牌分发到桌面,并通过移动有效负载分发。
  • On my REST API, support both methods of verification - header based and cookie-based - including CSRF protection for the cookie-based approach. 在我的REST API上,支持两种验证方法 - 基于头和基于cookie - 包括基于cookie的方法的CSRF保护。

Is there any reason why I wouldn't want to take this approach? 我有什么理由不想采取这种方法吗? I assume if I take XSS on my SPA as a serious risk, then I need a classic login-page for authentication to set the proper cookies because if I do authentication via the SPA, then any XSS attack could potentially intercept that as well (both on mobile and Desktop)! 我假设如果我在我的SPA上使用XSS是一个严重的风险,那么我需要一个经典的登录页面进行身份验证以设置正确的cookie,因为如果我通过SPA进行身份验证,那么任何XSS攻击都可能会拦截它(两者都有)在手机和桌面上)! However, on mobile, I'd need to inject the JWT into SPA, maybe through some custom DOM element (meta tag?), but at that point I can just let the SPA perform the login and not consider XSS a threat on mobile devices. 但是,在移动设备上,我需要将JWT注入到SPA中,可能通过一些自定义DOM元素(元标记?),但此时我可以让SPA执行登录,而不是将XSS视为移动设备上的威胁。 Cordova packages all assets into the install package so that's somewhat better but then why not take the same approach on the Desktop version? Cordova将所有资产打包到安装包中,这样有点好,但为什么不在桌面版上采用相同的方法呢?

My application takes very little user input, it is primarily a dashboard/reporting tool. 我的应用程序只需很少的用户输入,它主要是一个仪表板/报告工具。 There will be a "message center" but it's content should always be user-created (by only that user) and sanitized. 将有一个“消息中心”,但它的内容应始终由用户创建(仅由该用户创建)并进行消毒。 In my use-case then, would it be ok to deviate from "best practices" and rely on localStorage not counting XSS as a serious risk for my SPA? 在我的用例中,是否可以偏离“最佳实践”并依赖localStorage不计算XSS作为我的SPA的严重风险? This would simplify this entire thing (use HTML5 sessionStorage as originally planned) and reduce complexity, which would reduce attack surface for potential security blunders. 这将简化整个过程(按原计划使用HTML5 sessionStorage)并降低复杂性,这将减少潜在安全性失误的攻击面。 I just want to make sure I understand the risks before moving forward. 我只想确保在继续前进之前了解风险。

Is there no secure way to make this secure other than by building a native app for mobile and not using Cordova to convert my SPA to a mobile app? 除了通过构建移动本机应用程序而不是使用Cordova将我的SPA转换为移动应用程序之外,还有其他方法可以确保安全吗? I'd hate for this to be the case, but it might very well be. 我讨厌这种情况,但它可能很好。

I'd appreciate all thoughts on the matter! 我很感激所有关于此事的想法!

When thinking of designing javascript based cross-platform applications to run a mobile device, many of the caveats with designing regular web browser based applications do not necessarily apply. 在考虑设计基于javascript的跨平台应用程序来运行移动设备时,许多关于设计基于Web浏览器的常规应用程序的注意事项并不一定适用。

As far as security is concerned, whether you decide to use JWT or simple OAuth tokens, ensure that all your communications are via https. 就安全性而言,无论您决定使用JWT还是简单的OAuth令牌,都要确保所有通信都通过https进行。

Please use localStorage as much as you want. 请尽可能多地使用localStorage。 If you consider the anatomy of a http request, all it really is sending some text based message divided into multiple sections to a server. 如果你考虑一个http请求的解剖,它真的是发送一些基于文本的消息分成多个部分到服务器。 The header of the request is no more secure than any other part of it including the cookies. 请求的标头不比包括cookie在内的任何其他部分更安全。 So the points of interest from a security perspective are generation/validation/invalidation of the token, storage of the token on the device and the transport mechanism of the requests. 因此,从安全角度来看,兴趣点是令牌的生成/验证/无效,令牌在设备上的存储以及请求的传输机制。

  1. Generation/Validation/Invalidation: Generate the tokens on your server. 生成/验证/失效:在服务器上生成令牌。 Use some technology/strategy to ensure that there is no possibility for collisions or bleeding. 使用一些技术/策略确保不会发生碰撞或流血。 Also, ensure that your strategy will allow you invalidate a token on the server which then subsequently denies access to data requested from the server on further usage of the token. 此外,请确保您的策略允许您使服务器上的令牌无效,然后在进一步使用令牌时拒绝访问服务器请求的数据。 It is then up to you in your app to handle the users UI journey when the server denies access to resources. 然后由您的应用程序决定在服务器拒绝访问资源时处理用户UI之旅。
  2. How you store the token on the device is constrained to what the device OS make makes available to you. 如何将令牌存储在设备上受限于设备操作系统为您提供的功能。 Regarding whether using a native app is better than cross-platform, I think creating a native-cordova plugin to store your token using any specific native strategy if one is unsatisfied with the "out of the box" ones (such as local storage) is possible, although in my experience this is usually overkill. 关于使用本机应用程序是否优于跨平台应用程序,我认为创建一个native-cordova插件来使用任何特定的本机策略来存储您的令牌,如果对“开箱即用”(例如本地存储)不满意的话可能,虽然根据我的经验,这通常是矫枉过正。 Happy to be corrected on this one if anyone has a different experience. 如果有人有不同的经历,很高兴在这一个纠正。

  3. Please use HTTPS ALWAYS without exception for ALL Webservice end point communications. 对于所有Web服务端点通信,请毫无例外地使用HTTPS ALWAYS。 Is HTTPS foolproof, NO, but you wouldn't build a house without a front door simply because dedicated burglars could learn to pick locks. HTTPS是万无一失的,不,但是你不会因为专门的窃贼可以学会选择锁来建造一个没有前门的房子。 This secures the transport mechanism considerably. 这大大保证了运输机制。

Usually, this is all native apps have to work with too anyway. 通常,无论如何,这都是本机应用程序必须使用的。

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

相关问题 Angular SPA与REST API的关系 - How Angular SPA relates to REST API 如何使用Cordova和angularjs在混合移动应用程序中上传pdf文件? - How to upload pdf file in hybrid mobile app using cordova and angularjs? 有没有安全的方法可以在SPA中使用Basic Auth REST API创建用户会话? - Is there any secure way to create a user session in a SPA with a Basic Auth REST API? 如何只允许我的SPA调用我的公共休息API? - How to allow only my SPA to call my public rest API? Cordova-我怎么知道我的应用程序是使用HTML5 Geolocation API还是Cordova Geolocation插件? - Cordova - how do I know if my app is using the HTML5 Geolocation API or the cordova geolocation plugin? 如何使用现有的REST资源实施身份验证和授权SPA? - How to implement authentication and authorization SPA by using existing REST resources? 访问REST API时如何在Angularjs上保护身份验证标头 - How to secure my authentication headers on Angularjs when accessing REST API 使用API​​和Mongoose的AngularJS SPA - AngularJS SPA using API and Mongoose single-spa - 如何在不使用 SystemJS 的情况下加载 Angular 应用程序 - single-spa - how to load an Angular app without using SystemJS Web API和AngularJS SPA应用程序的身份验证 - Authentication of Web API and AngularJS SPA app
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM