preface
In learning Javaweb, we have been stressed that there are four scopes in Javaweb: pageContext, Request, Session, and Application.
The pageContext domain
The variables in the page are available only on the current page.Request the domain
The valid scope of the object in is the current request scope.The session domain
The valid scope of the object in is the current session scope.The application domain
The effective range of the object in is where the entire application is active.
After understanding the basic concepts, we can conclude that in order to conduct network communication, we generally use request and session. Since the scope of the request is only valid within the scope of the request, the data is automatically destroyed after each request. However, sometimes we want to store some long-lived data, such as login information, user information, etc., which the request domain cannot do.
A server session and a client (browser) cookie are similar in nature, for example, they can store data for a certain period of time. If the Cookie mechanism is the “pass” on the client, then the Session mechanism is the “customer list” composed of multiple “passes”. “In theory, these two memories are unrelated. But because of their similar nature, Java JSPS, Spring’s Thymeleaf template, link them together. Making people create sessions and cookies is consistent.” Take JSP for example, JSP is a special servlet program, although we write HTML statements in it, but it is actually a servlet by some means to turn into a front-end page. The Spring and Thymeleaf templates also use this approach. Because sessions can store long-lived data, we can use sessions to store login information, user information, etc.
Session /cookie disadvantages:
cookie
It’s not very secure. Someone can analyze it and store it locallycookie
And carry oncookie
Deception.- A single
cookie
The limitation on the client side is3K
That is, a site is hosted on the clientcookie
No more than3k
. session
It will be stored on the server for a certain amount of time. When the volume of traffic, will take up the performance of the server.- If it is in a server cluster or a cross-domain service-oriented architecture, it is required
session
Data sharing in a domain, that is, each server can read itsession
. At this point, we’ll just have tosession
Data persistence, which is a very bad idea.
Bigger questions
If the user disables cookies in the browser Settings; Or your site is implemented using a technology that separates the front from the back. There’s no simple way to use a session. On the one hand, your data cannot be stored because there is no cookie in the browser. On the other hand, the connection between the front and back ends is torn, and the session set separately on the server cannot be synchronized to the cookie of the browser. At this point, we need to use another idea: open up a space on both the front and back end to store user information.
Tokens are such an idea. The process is as follows:
- The client requests login using the username and password.
- The server receives a request to verify the user name and password.
- After successful validation, the server regenerates a unique string (
Token
Token), and saves the token in the server’s cache, and sends the token to the client. - The client receives
Token
You can store it later, like inCookie
Or in theLocalStorage
In the water. - Each time a client requests a resource from the server, it must carry the resource signed by the server
Token
. - The server receives the request and then validates the client with the request
Token
If the validation succeeds, the requested data is returned to the client.
The benefits of token
In addition, token can not only solve this practical problem, but also bring many benefits.
- Stateless and extensible: Stored on the client side
tokens
Is stateless and extensible. Based on this statelessness and no storagesession
Information, the load balancer can transfer user information from one server to another. - Security: send in request
token
Instead of sending itcookie
Can preventCSRF
Cross-site request forgery. Even on the client sidecookie
storagetoken
.cookie
It is only a storage mechanism and is not used for authentication. andtoken
There is a time limit, after a period of time the user needs to re-authenticate. - Scalability: Ability to share data with other programs.
- Multi-platform cross-domain: each time the server is accessed with a token bound to its own information. In the service cluster environment, instead of accessing a specific server, the server is selected for processing by taking out data from the cache server and using a load balancer.
The realization of the Token
Preparation stage
- use
Mysql
The database - open
Redis
The cache - use
Springboot
The framework
Code segment
1. Login
<form id="login_form" class="login_form">
User name:<input type="text" name="username">
<br>
Password:<input type="password" name="password">
<br>
<input type="button" value="Submit" onclick="login()">
</form>
<script type="application/javascript">
function login(){
$.ajax({
type:"post"./ / post request
dataType:"json".// Returns the json format
url:"http://localhost:8080/login".// Request path
data: $("#login_form").serialize(), // Form serialization
success: function(result){
console.log(result) // Print the result
if(result.code == 200) {
/ / store token
localStorage.token = result.data; // Save the token to localStorage
location.href = "/index"; // Jump to the home page
}
},fail:function(err){
console.log(err)
}
});
}
</script>
Copy the code
@Resource
RedisTemplate<String, Object> redisTemplate; // Redis cache templates
@RequestMapping(value = "/login", method = RequestMethod.POST)
@ResponseBody
public Result login(String username, String password){
System.out.println(username);
System.out.println(password);
User user = userService.getUser(username, password);
if(user ! =null) {
// The login succeeds, and the token is generated
String token = UUID.randomUUID() + ""; // Generate a unique key using a UUID as a token
redisTemplate.opsForValue().set(token, user, Duration.ofMinutes(30L)); // Put the token in redis cache for half an hour
return new Result(200."Request successful", token);
}
return new Result(400."Request failed".null);
}
Copy the code
2. Resource access request
function requestToken(){
$.ajax({
type:"get".// Request mode
dataType: "json".// Return the format
url:"http://localhost:8080/getUser".// Request an address
headers : {
"token" : localStorage.token // Set the header. It is safer to put the token in the request header
},
success:function(result){
console.log(result)
}
})
}
Copy the code
@RequestMapping("/getUser")
@ResponseBody
public Result getUserOfLogin(HttpServletRequest request){
String token = request.getHeader("token"); // Get the token from the request header
Object user = redisTemplate.opsForValue().get(token); // Search the redis cache for the token
if(user ! =null) {
// Get success, encapsulate return value
return new Result(200."Request successful", user);
}
return new Result(400."Could not find user information".null); // The token may not exist or the token may have expired
}
Copy the code
3. Log out
function logout(){
$.ajax({
type:"get".
url:"http://localhost:8080/logout".
dataType:"json".
headers: {
"token":localStorage.token
},
success:function(result){
localStorage.removeItem("token"); // Clear the token on the browser side
},fail : function(err){
console.log(err)
}
})
}
Copy the code
@RequestMapping("/logout")
@ResponseBody
public Result logout(HttpServletRequest request){
String token = request.getHeader("token"); // Get the token from the request header
Boolean delete = redisTemplate.delete(token); // Delete the information in redis cache according to the token
if(delete){
return new Result(200."Logout successful".null);
}else{
return new Result(400."Logout failed".null);
}
}
Copy the code