Demand scenarios

Banning accounts is a common business requirement, especially in forum and community projects. When there are illegal users, we need to immediately ban their accounts.

The common design idea is to add a status field when designing the user table. For example, the value of status is 1, indicating that the account is normal, and the value of status is 0, indicating that the account is banned.

When we need to block an account, we only need to change the status value of the account to 0. When the other party logs in to the system again, we can detect that the status value is not 1 and prohibit the login.

This mode is simple, but it also has a big problem: what if the other party stays online and does not log out?

Since we only detect the status value at login, this means that if the other party does not take the initiative to log out, their session will remain active and valid.

How can you do that immediately after banning the account?

You might think of using an interceptor that blocks all requests from the user to detect account status: deny access at status=0 and allow requests at status=1

This solves the problem, but if every request has to run a database query, the database says you’re going after me like this, don’t you have a little bit of psychological pressure?

So what? The cache? It relieves performance pressure, but it doesn’t feel like a perfect solution.

The real problem is that on a normal system only 0.01% of users need to be blocked, and our real-time detection of the other 99.99% is an unnecessary waste of performance.

In the above scenario, what we really need is a kick offline operation, that is, we need to disable a user’s session immediately after he or she is blocked from logging in again

So, how to do real-time kick people off the line?

The author uses sa-Token authority authentication framework, this framework encapsulates the kick people offline operation call is very convenient, like other frameworks also need me to encapsulate a layer to do it.

Specific code

  1. First, addpom.xmlThe framework
<! -- Sa-Token permission authentication: http://sa-token.dev33.cn/ -->
<dependency>
	<groupId>cn.dev33</groupId>
	<artifactId>sa-token-spring-boot-starter</artifactId>
	<version>1.12.1</version>
</dependency>
Copy the code
  1. Write the account ID to the session when the user logs on
@RestController
@RequestMapping("user")
public class UserController {
	@RequestMapping("doLogin")
	public String doLogin(String username, String password) {
		// This is only for example simulation. Real projects need to query data from the database for comparison
		if("zhang".equals(username) && "123456".equals(password)) {
			StpUtil.setLoginId(10001);
			return "Login successful";
		}
		return "Login failed"; }}Copy the code
  1. Will specify the account id
// Logs out the session of the specified account. When the session accesses the system again, the NotLoginException exception is thrown. The scenario value is -5
@RequestMapping("kickout")
public String kickout(long userId) {
	StpUtil.logoutByLoginId(userId);
	return "Pick out success.";
}
Copy the code

The key code is stputil.logoutbyLoginId (userId), which causes the specified account to logout.

If you feel that the article is written well, please do not hesitate to point a thumbs-up for the article, your support is the biggest power of my update!

Finally, attach the project link:

  • Official documentation: sa-token.dev33.cn/
  • Gitee open Source address: gitee.com/sz6/sa-toke…
  • GitHub open Source: github.com/click33/sa-…