简体   繁体   English

安全PHP RESTful API

[英]Security PHP RESTful API

I'm starting to develop a simple PHP RESTful API. 我开始开发一个简单的PHP RESTful API。 After reading some tutorials, one of the features about REST is that the 阅读完一些教程之后,关于REST的一个特性就是

"... statelessness is key. Essentially, what this means is that the necessary state to handle the request is contained within the request itself, whether as part of the URI, query-string parameters, body, or headers" “......无状态是关键。本质上,这意味着处理请求的必要状态包含在请求本身中,无论是作为URI,查询字符串参数,正文还是标题的一部分”

Therefore, it means that my PHP server won't need to have $_SESSION ? 因此,这意味着我的PHP服务器不需要$ _SESSION? What kind of approach do you recommend ? 你推荐什么样的方法? Using a token (valid for a short limit of time) in the URL doesn't seem a bit unsecure? 在URL中使用令牌(在短时间内有效)似乎有点不安全吗? For example www.myapi.com/1233asdd123/get_user/12. 例如www.myapi.com/1233asdd123/get_user/12。

Many thanks. 非常感谢。

If you're a web developer of any sort, you'll have heard this sentence probably 1,000 times: "HTTP is a stateless protocol". 如果您是任何类型的Web开发人员,您可能会听到这句话大概1000次:“HTTP是无状态协议”。 This means that every session works with a token exchanged between the server and the client. 这意味着每个会话都使用服务器和客户端之间交换的令牌。

When you use PHP's built-in sessions, the server is actually doing exactly that, even if you don't realize it: it generates a session_id and passes it to the client. 当您使用PHP的内置会话时,即使您没有意识到,服务器实际上正是这样做的:它生成一个session_id并将其传递给客户端。 The client passes the session_id token back normally on a cookie; 客户端通常在cookie上传递session_id令牌; PHP allows including the session token also on the URL, as a GET parameter, but I personally recommend disabling that feature (disabled by default on PHP 5.3+). PHP允许在URL上包含会话令牌,作为GET参数,但我个人建议禁用该功能 (默认情况下在PHP 5.3+上禁用)。

In your case, yes, you won't be using PHP's sessions. 在您的情况下,是的,您将不会使用PHP的会话。
You create a table in your database storing all session tokens and the associated session. 您在数据库中创建一个表,用于存储所有会话令牌和关联的会话。

Tokens should have a short lifespan (for example, 30 minutes) and should be refreshed frequently. 令牌的使用寿命应该很短(例如30分钟),并且应该经常刷新。 Refreshes are important not only to extend the life of the session (every refresh gives you an extra 30 minutes or so), but also help fighting against thefts of the session key. 刷新非常重要,不仅可以延长会话的使用寿命(每次刷新都会给你额外的30分钟左右),还有助于防止会话密钥被盗。 In some REST servers we created, the session token lives for 30 minutes and users are given a new token on the first request made after 10 minutes the session started. 在我们创建的一些REST服务器中,会话令牌存在30分钟,并且会话开始10分钟后,第一个请求会向用户提供新令牌。 When clients are sent a new token, the old one is invalidated immediately. 当客户端发送新令牌时,旧令牌会立即失效。

You could pass the token to the server in any way, but adding it as a GET parameter is not an ideal solution for two reasons: 1. GET parameters are often written in the access logs of the servers and 2. users often copy/paste URLs and share them, and that can expose their session token. 您可以以任何方式将令牌传递给服务器,但是将其添加为GET参数并不是理想的解决方案,原因有两个:1。GET参数通常写在服务器的访问日志中2.用户经常复制/粘贴URL并共享它们,并且可以公开其会话令牌。
For API servers, the best approach is to include the session token in one of the headers of the HTTP request. 对于API服务器,最好的方法是将会话令牌包含在HTTP请求的一个标头中。 For example, you could set your Authorization header: Authorization: SessionToken 123123123 where 123123123 is your token and SessionToken is a string to tell the server to use your authorization method (you're free to choose your own name, as long as it's not one of the default methods like Basic ; be consistent, though!). 例如,您可以设置Authorization标头: Authorization: SessionToken 123123123其中123123123是您的令牌, SessionToken是一个告诉服务器使用您的授权方法的字符串(您可以自由选择自己的名称,只要它不是一个像Basic这样的默认方法;但要保持一致!)。

Security on API servers is normally obtained by using SSL. API服务器上的安全性通常通过使用SSL获得。 Basically, if you have an API server, you must protect it with HTTPS (SSL). 基本上,如果您有API服务器,则必须使用HTTPS(SSL)保护它。
There are methods to achieve security also without using SSL, but they require signing each request and are really complicate to implement and to use - and the overhead they add is probably bigger than the one of SSL. 有一些方法可以在不使用SSL的情况下实现安全性,但是它们需要对每个请求进行签名,并且实现和使用起来非常复杂 - 并且它们添加的开销可能比SSL更大。

A very common practice is to use a key value inside the URL: 一种非常常见的做法是在URL中使用键值:

www.myapi.com?key=ABCD1234 www.myapi.com?key=ABCD1234

It is not less/more secure than POSTing the string. 它比POST字符串更安全。 SSL encryption ensures that the whole payload cannot be intercepted by a man-in-the-middle. SSL加密可确保整个有效负载不会被中间人拦截。

More info : 更多信息 :

You also mentioned a temporary access (session token). 您还提到了临时访问(会话令牌)。 It is common in systems to log in using credentials (like the solution above) and obtain a temporary session token in the response. 在系统中使用凭证(如上面的解决方案)登录并在响应中获取临时会话令牌是很常见的。 The session token is then used instead of the login details to query the service. 然后使用会话令牌而不是登录详细信息来查询服务。 It reduces the exposition of credentials in case of interception, and if someone manages to steal the session token, it will be working only for a few minutes. 在拦截的情况下,它减少了凭证的展示,如果有人设法窃取会话令牌,它将只工作几分钟。 Good to have although not a necessity. 尽管不是必需的但是很好。

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

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