Login is often used in each website in a function, on the page we enter the account password, hit the Enter key, on the login, but the login principle behind this do you know?
Traditional login mode
The original login method is that each website has its own login system and independent account. Users need to log in again to access each system. The accounts can not be shared between systems, and the login status can not be shared, which will lead to some drawbacks:
- When employees need to use multiple internal systems of the company, they need to register an account in each system, and if the employee leaves, each system has to delete the account information of the employee separately
- Obviously this one user is using the system, but it has to log in several times
The root cause of the disadvantages of the above login mode is that the user’s login status cannot be shared. What does “status” mean? How to achieve “state sharing”?
Stateful versus stateless
As we all know, HTTP is a stateless protocol. Each time a client sends a request, it establishes a connection with the server, and then breaks the connection when the request is completed. This method can save the connection resources used during transmission, but there is also a problem: each request is independent, the server can not tell whether the request and the previous request is from the same user, and thus cannot determine the user’s login status.
To solve the problem of HTTP statelessness, Lou Montulli introduced cookies in 1994.
Cookie
A special message sent by the server to the client in the form of text, which the client carries with it every time it sends a request to the server.
With the Cookie, the server can get the information passed by the client, and if the information needs to be authenticated, it needs to pass the Session.
The client requests the server, and the server will allocate a memory space for this request
Session
Object.
Session
Object is used to record the user’s login information, each
Session
There should be one for each object
sid
.
sid
Is unique, after successful login server will
sid
Injected into the
cookie
The next login or request will carry this
cookie
authentication
Once we have cookies and sessions, we can authenticate the login.
To explain the meaning of authentication, authorization: authentication is to check whether the user is logged in; Authorization refers to what the user can do, such as what menus the user can see
Cookie + Session
Cookie + Session is the most classic login method, which is still used by a large number of enterprises.
Monomer login
When the user first logs in:
Users log in by visiting a.com/pageA and entering their password. After the server verifies that the password is correct, it creates the SESSIONID and saves it. The server side responds to the HTTP request and writes the SESSIONID into the Cookie via the Set-Cookie header.
Server side
SessionId
It may be stored in many places, such as memory, files, databases, etc.
After the first login is completed, subsequent accesses can be authenticated directly using cookies:
When a user visits the a.com/pageB page, the Cookie that was written the first time he or she logged in is automatically brought with him. The server side compares whether the sessionID in the Cookie is consistent with the sessionID stored on the server side. If so, the authentication is successful.
Single cluster
When the traffic is high, a server above certainly can not support, you need to cluster the server
In addition, there are two functions of reverse proxy:
- Request distribution, load balancing, reduce the node server access pressure
- each
Cookie
They all correspond to onedomain
.a.com
A request from a domain name will only carry a request from that domain nameCookie
, then accessb.com
Page is not carrieda.com
In the domain nameCookie
, through reverse proxy to the same domain name (d.com), so that each node server can receive the Cookie under the domain name (d.com)
At the same time, sessions cannot be stored in the Tomcat memory of each node server, which will cause sessions not to be shared, and it is necessary to login again when the access is switched from A.com to B.com. In order for each node server to share sessions, Tomcat has a built-in clustering method that synchronizes the Session in memory of the node Tomcat by changing the Tomcat configuration file:
- Modify the
server.xml
, uncomment<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
- Modify the application
web.xml
, add nodes<distributable />
However, this approach has the following disadvantages:
- Each service needs to modify the configuration file
- bandwidth
- Copy when the server is out of memory
Session
May causeSession
The loss of
Is there a better way to solve the Seesion consistency problem?
File system? Database? Distributed caching?
In fact, all of these can be, but the performance is different, the file system, database performance is not very high, distributed cache to solve this problem
There are two kinds of distributed caches: 1. MenCache; 2, Redis; Redis storage will still be used in more scenarios. ConcurrentHashMap stores the JVM heap memory used, while Redis uses physical memory.
Session- Single Sign-On
The above is a system login, if we want to log in multiple systems for the same account how to do?
Through reverse proxy to the same domain name (o.com), so that each node server can receive the Cookie under the domain name (o.com), but how do we know which cluster site users like to visit?
The solution is to reverse proxy the site to the same domain name, and establish the mapping relationship between the route or the second-level domain name and the cluster site. In general, the route will be used for mapping to determine which cluster site the user wants to visit, and finally the node service will be polled and distributed to
{https://o.com/seller/#/xxx:l.com, https://o.com/admin/#/xxx:m.com, https://o.com/mall/#/xxx:n.com,}
The problem with Cookie + Session
Although we have completed login verification using Cookie + Session, there are still some problems:
- Because the server side needs to connect with a large number of clients, it also needs to store a large number of
Session
, which can cause the server to become overstressed. - If the server side is a cluster, using Seesion replication, the synchronous login state needs to be set
Session
Synchronize to each machine, virtually increase the maintenance cost of the server.
Cookie + Token
In order to solve many problems exposed by the Session + Cookie mechanism, we can use the Token login mode.
Token
Is a string generated by the server as a token requested by the client. After the first login, the server generates one
Token
And returns it to the client, who only needs to take this with him for subsequent access
Token
To complete the identity authentication.
Monomer login
When the user first logs in:
- The user enters the password and clicks Login.
- Server side to verify the account password is correct, create
Token
. - The server side will
Token
Returns to the client byThe client is free to save. - When accessing subsequent pages:
- The user to access
a.com/pageB
Bring the one you got the first time you logged inToken
. - Server-side Validation
Token
, the authentication is successful.
The characteristics of the Token mechanism
Based on the above case, we can analyze the advantages and disadvantages of Token:
- No storage is required on the server side
Token
, so there will be no pressure on the server side, even if the server cluster, there is no need to increase the maintenance cost. Token
I can store it anywhere on the front end, I don’t have to store it inCookie
In, improve the security of the page.Token
After it is issued, it remains in effect for as long as it is in effect, if the server wants to recall itToken
The permissions are not easy.
How to generate Token
There are many ways to do Token verification, but there are some standard methods, such as JWT, which is pronounced JOT for JSON Web Tokens. The JWT standard Token has three parts:
- Header:
- Payload
- (Signature)
The middle is separated by dots and is all Base64 encoded, so the actual Token looks like this:
eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ.SwyH TEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc
Header
Each JWT token has a header, or header data, inside it. It contains the algorithm used and whether the JWT is signed or encrypted. The main point is to explain how to handle the JWT token.
The contents of the header may vary depending on the type of JWT, such that an encrypted JWT contains the encryption algorithm used. The only thing to include in the header is the alg attribute, which in the case of encrypted JWT is the signature or decryption algorithm used. In the case of unencrypted JWT, the value of this property should be set to None.
Like:
{
"alg": "HS256",
"typ": "JWT"
}
This means that the JWT algorithm is HS256. The content above has to be encoded in base64url, so it looks like this:
eyJhbGciOiJIUzI1NiJ9
This part of JSON is Base64 encoded to form the first part of the Token.
Payload
Payload contains the contents of the Token, some of which are standard fields, and you can add other contents as required. Here are the standard fields:
- Iss: Issuer
- Sub: Subject B
- Aud: the Audience
- Expiration time, Expiration time
- Diagindex.nbf: Not before
- IAT: Issued AT
- Jit: JWT ID
The Payload below, for example, uses two standard fields, the ISS issuer, and the exp expiration time. There are also two custom fields, one for name and one for admin.
{
"iss": "ninghao.net",
"exp": "1438955445",
"name": "wanghao",
"admin": true
}
This is what base64url encoding looks like:
eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ
Signature
The final part of the JWT is the Signature, which has three parts. First, it’s a base64-encoded header.payload, and then it’s encrypted using an encryption algorithm. This password is stored secretly on the server side.
- header
- payload
- secret
const encodedString = base64UrlEncode(header) + "." + base64UrlEncode(payload);
HMACSHA256(encodedString, 'secret');
When it’s done, it looks like this:
SwyHTEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc
The final Token generated on the server and sent to the client looks like this:
eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ.SwyH TEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc
When the client receives the Token, it stores it and carries it with it the next time it sends a request to the server. The server receives the Token, validates it, and returns the desired resource to the client.
Issue and validate the JWT
To implement the JWT-based Token authentication method in your application, you can start by looking for a feature pack that issues and validates JWT. No matter what language, system, or framework your back-end application uses, you should be able to find packages that provide similar functionality.
Issued by JWT
Add a random.js file to your project, such as index.js, and add the following code to the file:
// Token data const payload = {name: 'wanghao', admin: // sign Token = jwt.sign(payload, secret, {expiresIn: // sign) // sign Token = jwt.sign(payload, secret, {expiresIn: '1day'}) // Output the issued Token console.log(Token)
JSONWebToken is used to issue a token using the jwt.sign function provided in JSONWebToken. The sign method takes three arguments:
- Playload: Some of the data to be included in the issuing token.
- Secret: The key used to issue the token, which is also needed to authenticate the token.
- Options: Some other options.
Verify the JWT
To verify the effectiveness of JWT, make sure that the user’s JWT is issued by ourselves. First, we need to get the user’s JWT Token, and then verify it with the method JWT.verify. If it is not the Token issued by our own Secret, the verification will not pass. This method is provided in the Node.js JSONWebToken package. In other application frameworks or systems, you will probably find a similar method to verify JWT.
// verify Token jwt.verify(Token, 'secret', (error, decoded) => { if (error) { console.log(error.message) return } console.log(decoded) })
Token Single Cluster
Token- Single Sign-On
What are the possible problems with using Tokens?
-
Can tokens be stolen?
The Token is not easy to steal in HTTPS, where the SSL protocol encrypts both the header and the body of the request. This means that the Cookie transmitted to the server is encrypted and the request cannot be easily decrypted if intercepted. Of course, if your computer has installed some malicious program implanted Trojan horse, steal your account and token, this can’t be helped, so advocate healthy Internet surfing and refuse to pirate software.
- What if the key is placed directly in the server and stolen by the developer?
Fire prevention and anti-theft but can not prevent their own family how to do? The key is usually not placed directly in the project, but in the file system orgithub
And different environments have different keys. In order to prevent developers from printing after reading the key, a code review link can be added. The code submitted will be automatically scanned. If the key code of printing key is found, the staff will be fired. In addition, the key may be changed from time to time. - How to renew the Token? If the user is asked to go through the above process again and apply for a new token, the experience is probably not good and it is not necessary. When a server issues a token, it issues two tokens at once, one to retrieve data and the other to retrieve a new token (Refresh Token field). Before the token expires (the front-end countdown is judged to be expired or the request finds a login exception), the user issues a request to update the token with Refresh Token.
CAS
Whether Session or Token is used to realize single sign-on, each subsystem above needs to implement its own authentication service. However, their Session or Token is shared and can be separated into a central authentication service (CAS). All subsystems log in and authenticate through the central authentication service.
CAS is the abbreviation of Central Authentication Service, Central Authentication Service, a separate open instruction protocol. CAS is an open source project initiated by Yale University, which aims to provide a reliable single sign-on method for Web applications. CAS consists of two parts: CAS Server and CAS Client. CAS Server needs to be independently deployed and is mainly responsible for user authentication; CAS Client handles access requests to the Client’s protected resources and redirects to CAS Server when it needs to log in.
The CAS Client is deployed with the protected Client application to protect the protected resources as a Filter. For each Web request that accesses a protected resource, the CAS Client will analyze whether the HTTP request for that request contains a Service Ticket. If it does not contain a Service Ticket, the Client will redirect the request to the specified CAS Server login address. And pass the Service (that is, the address of the destination resource to be accessed) so that if the login is successful, you can go back to that address. The user enters the authentication information in the third step. If the login is successful, CAS Server will randomly generate a fairly long, unique and non-forgeable Service Ticket and cache it for future verification. After that, the system will automatically redirect to the address where the Service is located. And set a Ticket for the Client browser to grant Cookie (TGC). After the CAS Client gets the Service and the newly generated Ticket, it verifies the identity with the CAS Server in steps 5 and 6. To ensure the validity of a Service Ticket.
In this protocol, all interactions with CAS are conducted using SSL protocol to ensure the security of ST and TGC. There are two redirects during the protocol, but Ticket validation between CAS Client and CAS Server is transparent to the user.
In addition, the CAS protocol also provides Proxy (Proxy) mode to adapt to more advanced and complex application scenarios. For detailed introduction, you can refer to the relevant documents on the official CAS website.
The figure above is the standard process of CAS official website. The specific process is as follows:
- The user to access
app
The system,app
The system is required to log in, but the user is not logged in. - Jump to
CAS server
, i.e.,SSO
Log in to the system, as shown in the following pictureCAS Server
We’re all calledSSO
System.SSO
The system is not logged in, the user login page pops up. - The user fills in the user name and password.
SSO
After the system authentication, the login status will be writtenSSO
thesession
, browser (Browser
) writeSSO
Under the domain ofCookie
. SSO
One is generated when the system login is completeST (Service Ticket)
“And then jump toapp
The system will alsoST
Pass as a parameter toapp
System.app
System to get theST
After, from the background toSSO
Send the request, verify itST
Whether or not it works.- After verification,
app
The system writes the login statussession
And set theapp
Under the domain ofCookie
.
At this point, cross-domain single sign-on is complete. When we visit the APP system in the future, the APP will be logged in. Next, let’s look at the flow when accessing the App2 system.
- The user to access
app2
The system,app2
System not logged in, jump toSSO
. - Due to the
SSO
You are already logged in. You do not need to re-login authentication. SSO
generateST
, the browser jumps toapp2
System and willST
Pass as a parameter toapp2
.app2
getST
, background accessSSO
To verifyST
Whether or not it works.- After successful verification,
app2
Write the login statussession
And, inapp2
Under the domain to writeCookie
.
oAuth2.0
In traditional client-server authentication, when a client requests restricted access to a resource (a protected resource) on the server, the resource owner’s credentials need to be used to authenticate on the server. A resource owner needs to share its credentials with third parties in order to give third-party applications access to restricted resources. This leads to some problems and limitations:
- Third-party applications need to store the resource owner’s credentials for future use. This credential is usually a plaintext password.
- The server needs to support cryptographic authentication, despite its inherent security pitfalls.
- Third-party applications gain too broad access to the resource owner’s protected resource, which prevents the resource owner from restricting access duration or permissions to a limited subset of the resource.
- Resource owners cannot revoke access from one third party without affecting other third parties, and must change their passwords to do so.
- Compromise with any third party application results in compromise with the end user’s password and all data protected by that password.
OAuth addresses these issues by introducing an authorization layer and separating the client role from the resource owner role. In particular, OAuth sets an authorization layer between the “client” and the “service provider”. The client cannot log directly into the service provider, only into the authorization layer, which differentiates the user from the client. The client login authorization layer uses a different token than the user’s password. The user can specify the scope and validity of the authorization layer token when logging in. After the Client logs on to the Authorization Layer, the Service Provider opens the Customer’s stored data to the Client based on the scope and validity of the token.
CAS and OAuth2 differ
CAS
The single sign-on system ensures the security of the client’s user resources.OAuth2
Is to ensure the security of user resources on the server side;CAS
The final information the client wants to get is whether the user has permission to access me (CAS
Client);oauth2
The final information obtained is that I (oauth2
Can the service provider’s user resources enable you to (oauth2
Client side) access;CAS
Single sign-on, resources are on the client side, notCAS
The server side. The user toCAS
After the server provides the username and password, asCAS
The client is not aware of this. Just give it to the clientST
, then the client is not sure about thisST
Is it fake by the user or is it really valid? So hold thisST
Go to the server and ask again. The user gave me a valid messageST
It’s not validST
I can only give this user access if it’s valid.OAuth2
Authentication, resources are all thereOAuth2
On the service provider side, the client wants to claim the user’s resources. So in the most secure mode, the server cannot return directly after the user is authorizedtoken
, via redirect to the client, because of thistoken
It could be intercepted by a hacker if a hacker intercepts thistoken
, the user’s resources are exposed to this hacker. The clever server sends an authenticationcode
To the client (via redirect), the client in the background, throughhttps
The way, with thiscode
, and another set of pre-agreed passwords between the client and the servertoken
And refreshtoken
This process is very safe. If a hacker intercepts itcode
He didn’t have the pre-agreed code, and he couldn’t get ittoken
. suchoauth2
Can ensure that the request of resources this matter, is agreed by the user, the client is also recognized, you can rest assured to send the resources to the client.CAS
The login andOAuth2
The biggest difference in the process is, passST
orcode
To authenticate, do you need to pre-negotiate the password.
OAuth defines four types of roles:
- An entity that allows the resource owner to grant access to a protected resource. When the resource owner is a person, it is called an end user.
- Resource Server A server that hosts a protected resource and is able to receive and respond to requests for the protected resource using an access token.
- An application where a client initiates a request for a protected resource on behalf of the resource owner using the resource owner’s authorization. The term “client” does not refer specifically to any specific implementation characteristics (for example, whether the application executes on a server, desktop, or other device).
- The authorization server issues an access token to the client server after successfully authenticating the resource owner and obtaining authorization.
The interaction between the authorization server and the resource server is beyond the scope of this specification. The authorization server can be the same server as the resource server, or it can be a separate entity. An authorization server can issue access tokens accepted by more than one resource server.
Abstract protocol flow
+--------+ +---------------+ | |--(A)- Authorization Request ->| Resource | | | | Owner | | |<-(B)-- Authorization Grant ---| | | | +---------------+ | | | | +---------------+ | |--(C)-- Authorization Grant -->| Authorization | | Client | | Server | | |<-(D)----- Access Token -------| | | | +---------------+ | | | | +---------------+ | |--(E)----- Access Token ------>| Resource | | | | Server | | |<-(F)--- Protected Resource ---| | +--------+ +---------------+
The abstract OAuth 2.0 process shown in the figure describes the interaction between the four roles, including the following steps:
(A) The client requests authorization from the resource owner. Authorization requests can be made directly to the resource owner (as shown in the figure) or, preferably, indirectly through the mediation of the authorization server. (B) The client receives an authorization, which is a credential representing the authorization of the resource owner, expressed using one of the four license types defined in this specification or using an extended license type. The type of authorization depends on the method used by the client to request authorization and the type supported by the authorization server. (C) The client authenticates with the authorization server and presents the authorization to request an access token. (D) The authorization server verifies the identity of the client and verifies the authorization and, if valid, issues an access token. (E) The client requests a protected resource from the resource server and authenticates by presenting an access token. (F) The resource server validates the access token and, if valid, processes the request. A better way for A client to obtain authorization from the resource owner (as shown in steps (A) and (B)) is to use the authorization server as A mediator
Authorization is a credential that authorizes (access to a protected resource) on behalf of the resource owner and is used by the client to obtain access tokens. The RFC 6749 specification defines four types of license — authorization code, implicit license, resource owner password credential, and client credential — as well as extensibility mechanisms for defining other types.
Use GitHub authorization as an example to describe authorization code types
First, you need to register your application on GitHub. After registration, GitHub will return the client ID (client_id) and client secret (client_secret).
The client front-end desk is authenticated by Session:
The client front-end desk is authenticated by Token:
See: Token-based Authentication: JSON Web Token (with: Node.js project) CAS Seesion will copy OAuth 2.0 in four ways. RFC 6749 Chinese version RFC 6749-OAuth 2.0 authorization framework for simplified Chinese translation github OAuth documentation