RESTful authentication - resulting poor performance on high load?

时光毁灭记忆、已成空白 提交于 2019-11-30 08:32:38
kvista

The spirit of REST is statelessness. This does not mean that client state cannot be persisted by a service, but in practice it does mean that client state held in memory by a server is generally a bad thing.

Instead of keeping authentication data in memory, or going to the DB for verification every time, what you can do is keep a function in memory (i.e., code) that is used to crypt/decrypt user information. This is a technique that is also suggested by:

What should I store in cookies to implement "Remember me" during user login

So, for example, what you would do is the following:

  1. When a client first contacts the service, it has no cookie.
  2. You issue a cookie that contains user info and "sign" it using your function (which all servers, running your code, can do)
  3. When the client contacts the service again, you check if it has a cookie; if not, repeat (2).
  4. However, if it does have a cookie, you attempt to decrypt (again, using your single function which is replicated across your infrastructure) and verify that you can unwrap and digest that user ID info.
  5. This verifies the user and gives you identity info, all without going to the DB more times than is necessary. And it's RESTful.

Keep in mind that this "function" I describe is not a novel thing - it's a standard secure hash, but one that is based off a unique private key that only your collective servers know about. And you can rotate such a key, etc. as needed.

You only verify the credentials (e.g. username/password) at the time of login. When the user successfully logs in, you send them a cookie containing an unguessable "session ID". This session ID becomes the token which allows further access after credentials have been checked. The server application verifies the token by finding it in some in-memory data structure. The tokens expire after some reasonable amount of time, to prevent exhaustion of memory. The tokens are explicitly removed from the in-memory store if the user explicitly logs off (pressed the 'logoff' button).

It is important to use https when sending and receiving the token -- otherwise sniffing the token allows a hacker to "hijack the session." In other words, use https for the entire application workflow from login to logout.

RESTful services are supposed to be stateless, so yes a client does need to provide authentication credentials every time it calls a RESTful service.

There is no real benefit to replacing username/password with some kind of hash or token or session ID. All are just different forms of authentication that must be validated against some bit of data in persistent storage. The drawback of sessions and tokens is that they violate the statelessness requirement.

If database performance is an issue then use memcached or some other high-performance data cache. You'll probably find that ALL of your database access benefits from this, not just retrieving auth credentials.

Finally, there's no problem with sending username/password every time as long as you're doing it over HTTPS. Never, ever send important auth credentials over plain text HTTP.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!