--further discussion of some common problems based on token authentication
SOURCE Link: here
Hara Matias Woloski
A few weeks ago we published a short essay, "The Comparison of cookies and tokens in single-page applications" (mainly in the case of ANGULARJS applications). The community was interested in this topic, so we went on to publish the second "token-based authentication in real-time framework such as Socket.io". While we are still passionate about this topic, we decided to write another article to further explore common issues based on token authentication. Let's get started.
1.Tokens needs to be stored in local Storage, Session Storage or cookies
In the context of tokens being applied to a single page application, someone raised the question: what happens to tokens when the page is refreshed in a browser. The answer is simple: you need to save the token in the local Storage, session Storage, or the client's built-in cookie, and it will be polyfills as a cookie if the browser does not support Session Storage.
You might want to ask, "but if I keep my token in a cookie, it's dangerous." In fact, in this case, you use cookies as a storage mechanism rather than as a verification mechanism (that is, the web framework does not use cookies to authenticate users, so there is no risk of XSRF attacks)
2.Tokens will expire like a cookie, but you have more control over it.
Tokens has a lifecycle (controlled by attributes in the JSON Web tokens exp
), otherwise the user can log in once but never need to authenticate. Cookies also have a life cycle for the same reason.
In cookies, the life cycle is different for the following conditions:
1. Cookies are destroyed when the browser is closed (such as session cookies)
2. You can also implement a server-side check mechanism (usually done by the web framework), and you can set the lifecycle or sliding window life cycle.
3.Cookies can be permanent for a period of time (even if the browser is closed, it will not be destroyed)
In tokens, once expired, you only need to get a new token. You can write an endpoint to update tokens:
1. Verify the old token
2. Check if the user is still logged in or visiting your website
3. Create a new token at the time of renewal
You can even write the time tokens are generated and force the user to log back in about two weeks.
App.post ('/refresh_token ',function(req, res) {//Verify the existing token varProfile =jwt.verify (Req.body.token, secret); //if more than-old, force login if(Profile.original_iat-NewDate () > 14) {//IAT = = Issued at returnRes.send (401);//re-logging } //Check if the user still exists or if authorization hasn ' t been revoked if(!valid)returnRes.send (401);//re-logging //issue a new token varRefreshed_token = jwt.sign (Profile, secret, {expiresinminutes:60*5 }); Res.json ({token:refreshed_token});});
3.local/session Storage cannot cross the domain, please use cookies for marking
If you set the role of the cookie to a domain .yourdomain.com
, then it can be yourdomain.com
accessed in and app.yourdomain.com
. It is app.yourdomain.com
also convenient to verify the cookie if the user is redirected to the primary domain.
Tokens is stored in local/session storage, which means that there is no mutual access between different domain names (even subdomains). So what are you going to do about it?
One of the practices is that when the user app.yourdomain.com
has verified in, you generate a token and set a cookie that has a domain name to .yourdomain.com
mark the user's login.
$.post ('/authenticate, function () { //store token on local/session storage or cookie ... . Create a cookie signaling that user was logged in $.cookie (' Loggedin ', Profile.name, '. yourdomain.com ');}) ;
Then, you can
yourdomain.com
Verify the existence of the cookie and redirect to
app.yourdomain.com
。 Tokens can be used in the subdomain of the app (if tokens are still valid).
There may be situations where a cookie exists and token has been deleted. In this case, the user must log on again. It is emphasized here that, as we have said before, we do not use cookies as a validation mechanism, but as a storage mechanism that can store information across domains.
4. Each cors request will be preceded by a pre-request
It has been pointed out that the authorization header is not a simple header, so a pre-request needs to be sent before a request is sent to a particular URLs.
OPTIONS https://api.foo.com/barGET https://api.foo.com/bar Authorization:bearer .... OPTIONS https://api.foo.com/bar2GET https://api.foo.com/bar2 Authorization:bearer .... GET https://api.foo.com/bar authorization:bearer ....
At this point you need to send
Content-Type: application/json
。
As a reminder, the OPTIONS
request itself does not have authorization header information, so your web framework needs to do OPTIONS
some processing with subsequent requests (hint: Microsoft's IIS has some problems with this for some reason).
5. When you are dealing with streaming media, please use token to get the signature request
When using cookies, you can easily trigger file downloads and some text streams. However, in tokens, the request is done through XHR, and you cannot rely on it. The solution is to generate a signature request like AWS, for example, Hawk Bewits is an excellent framework to support this approach:
Request:
post/download-file/123authorization:bearer ...
Response:
Ticket=lahdoiasdhoiwdowijaksjdoaisdjoasidja
Among them, the ticket is stateless. It is generated by Url:host + path + query + headers + timestamp + HMAC with an expiration time. So it can be used to download files for a period of time (say, 5 minutes).
You will be redirected to /download-file/123?ticket=lahdoiasdhoiwdowijaksjdoaisdjoasidja
. The server verifies that the ticket is legitimate and completes the next business operation.
6. Dealing with XSS is easier than xsrf
Cookies have the ability HttpOnly
to set tags, which allows only servers to access rather than JavaScript. This is useful because it protects cookies from being injected into the client code attacks (XSS).
Because tokens is stored in local/session storage or in a client-built cookie, this is susceptible to XSS attacks and the attacker acquires tokens. This is a worrying issue, so you need to set the tokens to a shorter time to live.
At the cookie level, a major attack is xsrf. The real situation is that XSRF is one of the most overlooked attacks. Common developers may not even understand this risk, so many applications lack the mechanism for anti-xsrf attacks. However, everyone knows what is injected. Simply put, if you allow the user input to be rendered without escaping, then your app is exposed to XSS attacks. According to our experience, it is easier to prevent XSS than XSRF. Because not all web frameworks have built-in anti-xsrf mechanisms, it is much easier to protect against XSS in the vast majority of template engines that support escaped syntax.
7. Each request will need to send token, please note its size
When you send an API request every time, you need to attach the token to your head and send it Authorization
out.
Get/fooauthorization:bearer ... 2KB token ...
And the comparison of cookies
Get/fooconnect.sid: ... Bytes Cookies ...
The size of the token depends on how much information you have inside it, which can be quite large. In contrast, Session cookies save only one tag (CONNECT.SID,PHPSESSID, etc.), and the main content is stored on the server (only one of the servers is stored in memory and stored in the database in the server farm).
Now you can fully implement a mechanism like tokens. This token has the basic information you need, and you can add more information to the token based on the invocation of each API on the server. Cookies can do this, but the difference is that tokens has a benefit that you can control it completely, after all, it's part of your code.
Get/fooauthorization:bearer ... Bytes token ...
On the service side:
App.use ('/api ', // Validate tokenfirst expressjwt ({secret:secret}), // enrich req.user with more data from DB function(req, res, next) {
= get_from_db (); Next (); });
It is important to note that you can completely save the session in a cookie (not just a tag). But not all web platforms support this, for example, in node. js, you can use Mozilla/node-client-sessions.
8. If you store sensitive information, please encrypt the token
Token signatures prevent the tampering of information, and TLS/SSL can prevent man-in-the-middle attacks. But if you include sensitive information about your users (social Security numbers, etc.), you need to encrypt them. JWT (JSON web Tokens) uses Jwe (JSON web encryption) as a specification, but most class libraries have not implemented jwe, so the simplest approach is to use AES-CBC mode for encryption as follows.
App.post ('/authenticate ',function(req, res) {//Validate user //Encrypt profile varencrypted = {token:encryptaessha256 (' shhhh '), Json.stringify (profile))}; //Sing the token vartoken = Jwt.sign (encrypted, secret, {expiresinminutes:60*5 }); Res.json ({token:token});} functionencryptAesSha256 (password, texttoencrypt) {varcipher = Crypto.createcipher (' AES-256-CBC '), password); varcrypted = Cipher.update (texttoencrypt, ' utf8 ', ' hex ')); Crypted+ = cipher.final (' hex ')); returncrypted;}
Of course, you can also save sensitive information in a database like # #.
9.JSON Web tokens can be used in OAuth
Tokens are often associated with OAuth. OAuth2 is a protocol that resolves identity authentication authorization. After the user agrees to authorize access to their data, the authentication server returns one access_token
so that the corresponding APIs can be accessed using the user's identity.
Usually these tokens are opaque. They are called bearer
tokens, and are stored in a random string into a hash table of some kind, and store in the server (database, cache, etc.). The content includes the expiration time, the scope of the request (for example, access to the Friends List), and authorized users. The token is then sent to the server when the API is called, and the server looks up the information in the hash table and starts validating it (such as whether token has expired or exceeded the request scope).
The main difference between this token and the signature token (such as JWT) that we've been discussing is that the latter is stateless, and they don't need to be stored in a hash table, so it's a more lightweight approach. OAuth2 does not have a specified access_token
format, so you can return a JWT with a "request scope, permission list, and expiration Time" included in an authorized server.
10.Tokens is not a panacea, please carefully consider the License usage scenario
A few years ago, we implemented a token-based architecture for a large company. This is a company with more than 100,000 employees with a lot of information to be protected. They want to implement a centralized management organization system based on "authentication and Authorization". Imagine "User x can read the application scenario for the ID and name of the clinical trial y in the W Region Z hospital." This fine-grained authorization, you can imagine, whether in technology or management, is difficult to deal with.
- The tokens will get very big.
- Your apps/apis will become complicated.
- It's hard to let anyone grant permission.
In the context of information architecture, we have abandoned this work to ensure that reasonable scopes and permissions are created.
Conclusion: To resist the temptation to convert everything into tokens, be sure to do all kinds of analysis before using this method.
This article fixed link: http://zoufeng.me/2015/08/12/ten-things-you-should-know-about-tokens-and-cookies
Recommended a PHP Advanced Development Group (467634807), like watering and chatting do not enter ~
10 things you need to know about tokens