User login authentication is Web A very common business in applications , The general process is like this :
- The client sends the user name and password to the server
- After the server-side verification passes , In the current session (session) Save relevant data in , For example, login time 、 Sign in IP etc. .
- The server returns a... To the client session_id, The client saves it in Cookie in .
- When the client sends a request to the server again , take session_id Send it back to the server .
- On the server side session_id after , Identify the user .
In the case of a single machine , There is no problem with this model , But for front and rear end separation Web applications , It's very painful . So there is another solution , The server side will no longer save session data , Instead, save it on the client , Each time the client initiates a request, it sends the data to the server for verification .JWT(JSON Web Token) It is a typical representative of this scheme .

One 、 About JWT
JWT, It's the most popular Cross domain Certification solutions : The client initiates a user login request , After the server receives and authenticates successfully , Generate a JSON object ( As shown below ), And then it's returned to the client .
{
"sub": "wanger",
"created": 1645700436900,
"exp": 1646305236
}
When the client communicates with the server again , Put this JSON Take the object with you , As a certificate of mutual trust between the front and back ends . After the server receives the request , adopt JSON Object to authenticate the user , This eliminates the need to save any session Data. .
If I use a user name now wanger And password 123456 Access programming meow (Codingmore) Of login Interface , So practical JWT It's a string that looks like it's encrypted .

In order to let everyone see more clearly , I copied it to jwt Its official website .

left Encoded Part is JWT Ciphertext , Intermediate use 「.」 Divided into three parts ( On the right side Decoded part ):
- Header( Head ), describe JWT Metadata , among
algThe algorithm of attribute representation signature ( At present, it is HS512); - Payload( load ), It is used to store the data that needs to be transferred , among
subProperty represents the subject ( The actual value is user name ),createdAttribute representation JWT Time of birth ,expProperty indicates the expiration time - Signature( Signature ), Signature of the first two parts , Prevent data tampering ; You need to specify a key on the server side ( Only the server side knows ), Can't leak to client , And then use Header The signature algorithm specified in , Follow the formula below to generate a signature :
HMACSHA512(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)
After you figure out the signature , And then Header、Payload、Signature Concatenate into a string , Intermediate use 「.」 Division , You can return it to the client .
The client gets JWT after , Can be placed in localStorage, It can also be placed in Cookie Inside .
const TokenKey = '1D596CD8-8A20-4CEC-98DD-CDC12282D65C' // createUuid()
export function getToken () {
return Cookies.get(TokenKey)
}
export function setToken (token) {
return Cookies.set(TokenKey, token)
}
When the client communicates with the server in the future , Just take this JWT, Generally placed on HTTP The header of the request Authorization In the field .
Authorization: Bearer <token>

After the server receives the request , Right again JWT To verify , If the verification is passed, the corresponding resources will be returned .
Two 、 actual combat JWT
First step , stay pom.xml Add... To the file JWT Dependence .
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
The second step , stay application.yml Add JWT Configuration item for .
jwt:
tokenHeader: Authorization #JWT Stored request header
secret: codingmore-admin-secret #JWT The key used for encryption and decryption
expiration: 604800 #JWT Beyond the deadline of (60*60*24*7)
tokenHead: 'Bearer ' #JWT Get the beginning of the load
The third step , newly build JwtTokenUtil.java Tool class , There are three main ways :
generateToken(UserDetails userDetails): Generated according to the logged in user tokengetUserNameFromToken(String token): from token Get login uservalidateToken(String token, UserDetails userDetails): Judge token Whether it is still valid
public class JwtTokenUtil {
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.expiration}")
private Long expiration;
@Value("${jwt.tokenHead}")
private String tokenHead;
/**
* According to the user information token
*/
public String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>();
claims.put(CLAIM_KEY_USERNAME, userDetails.getUsername());
claims.put(CLAIM_KEY_CREATED, new Date());
return generateToken(claims);
}
/**
* According to the user name 、 Create time generation JWT Of token
*/
private String generateToken(Map<String, Object> claims) {
return Jwts.builder()
.setClaims(claims)
.setExpiration(generateExpirationDate())
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
/**
* from token Get login user name
*/
public String getUserNameFromToken(String token) {
String username = null;
Claims claims = getClaimsFromToken(token);
if (claims != null) {
username = claims.getSubject();
}
return username;
}
/**
* from token In order to get JWT Load in
*/
private Claims getClaimsFromToken(String token) {
Claims claims = null;
try {
claims = Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
} catch (Exception e) {
LOGGER.info("JWT Format validation failed :{}", token);
}
return claims;
}
/**
* verification token Is it still valid
*
* @param token From the client token
* @param userDetails User information from the database
*/
public boolean validateToken(String token, UserDetails userDetails) {
String username = getUserNameFromToken(token);
return username.equals(userDetails.getUsername()) && !isTokenExpired(token);
}
/**
* Judge token Is it invalid
*/
private boolean isTokenExpired(String token) {
Date expiredDate = getExpiredDateFromToken(token);
return expiredDate.before(new Date());
}
/**
* from token Get the expiration time in the
*/
private Date getExpiredDateFromToken(String token) {
Claims claims = getClaimsFromToken(token);
return claims.getExpiration();
}
}
Step four , stay UsersController.java Newly added login Login interface , Receive user name and password , And will JWT Return to the client .
@Controller
@Api(tags=" user ")
@RequestMapping("/users")
public class UsersController {
@Autowired
private IUsersService usersService;
@Value("${jwt.tokenHeader}")
private String tokenHeader;
@Value("${jwt.tokenHead}")
private String tokenHead;
@ApiOperation(value = " Log in and return to token")
@RequestMapping(value = "/login", method = RequestMethod.POST)
@ResponseBody
public ResultObject login(@Validated UsersLoginParam users, BindingResult result) {
String token = usersService.login(users.getUserLogin(), users.getUserPass());
if (token == null) {
return ResultObject.validateFailed(" Wrong user name or password ");
}
// take JWT Pass back to the client
Map<String, String> tokenMap = new HashMap<>();
tokenMap.put("token", token);
tokenMap.put("tokenHead", tokenHead);
return ResultObject.success(tokenMap);
}
}
Step five , stay UsersServiceImpl.java Newly added login Method , Query the user from the database according to the user name , Generate after password verification JWT.
@Service
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users> implements IUsersService {
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private JwtTokenUtil jwtTokenUtil;
public String login(String username, String password) {
String token = null;
// The password needs to be passed after being encrypted by the client
try {
// Query the user + User resources
UserDetails userDetails = loadUserByUsername(username);
// Verify password
if (!passwordEncoder.matches(password, userDetails.getPassword())) {
Asserts.fail(" Incorrect password ");
}
// return JWT
token = jwtTokenUtil.generateToken(userDetails);
} catch (AuthenticationException e) {
LOGGER.warn(" Login exception :{}", e.getMessage());
}
return token;
}
}
Step six , newly added JwtAuthenticationTokenFilter.java, Every time the client makes a request, it will respond to JWT To verify .
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
private static final Logger LOGGER = LoggerFactory.getLogger(JwtAuthenticationTokenFilter.class);
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Value("${jwt.tokenHeader}")
private String tokenHeader;
@Value("${jwt.tokenHead}")
private String tokenHead;
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain) throws ServletException, IOException {
// Get... From the client request JWT
String authHeader = request.getHeader(this.tokenHeader);
// The JWT It's the format we stipulated , With tokenHead start
if (authHeader != null && authHeader.startsWith(this.tokenHead)) {
// The part after "Bearer "
String authToken = authHeader.substring(this.tokenHead.length());
// from JWT Get user name
String username = jwtTokenUtil.getUserNameFromToken(authToken);
LOGGER.info("checking username:{}", username);
// SecurityContextHolder yes SpringSecurity A tool class of
// Save the security context of the current user in the application
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
// Obtain login user information according to user name
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
// verification token Is it overdue
if (jwtTokenUtil.validateToken(authToken, userDetails)) {
// Save the logged in user in a security context
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails,
null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
LOGGER.info("authenticated user:{}", username);
}
}
}
chain.doFilter(request, response);
}
}
JwtAuthenticationTokenFilter Inherited OncePerRequestFilter, This filter ensures that a request passes only once filter, It doesn't need to be repeated . in other words , Every time the client initiates a request , The filter will execute once .
This filter is very critical , Basically, I added comments to every line of code , Yes, of course , To make sure everyone can figure out what this class does , Let me draw another flow chart , So it's clear .

SpringSecurity Is a security management framework , You can talk to Spring Boot Application seamless connection ,SecurityContextHolder Is one of the key tool classes , Hold security context information , Who is the user who saves the current operation , Whether the user has been authenticated , Key information such as permissions owned by users .
SecurityContextHolder Default used ThreadLocal Policies to store authentication information ,ThreadLocal It's characterized by the data in it , Which thread has stored , Which thread can access . This means that after different requests enter the server , There will be different Thread To deal with , For example, threads A The request 1 User information is stored in ThreadLocal, Threads B Processing request 2 You can't get the user's information when you are .
So JwtAuthenticationTokenFilter The filter will do it every time a request comes JWT Validation of the , Ensure that the request from the client is secure . then SpringSecurity The next request interface will be released . This is also JWT and Session Fundamental difference :
- JWT You need to verify every request , And as long as JWT No expired , Even if the server is restarted , The certification is still valid .
- Session Without expiration, it is not necessary to re verify the user information , When the server is restarted , The user needs to log in again to get a new Session.
in other words , stay JWT Under the scheme of , The key saved on the server side (secret) We must not divulge , Otherwise, the client can forge the user's authentication information according to the signature algorithm .
3、 ... and 、Swagger Add JWT verification
For back-end developers , How to be in Swagger( Integrated Knife4j Beautify ) Add JWT What about verification ?
First step , visit login Interface , Enter your user name and password to log in , Get the information returned by the server JWT.

The second step , Collect the data returned by the server tokenHead and token, Fill it in Authorize( Be careful tokenHead and token There is a space between ) Complete login authentication .

The third step , When another interface is requested ,Swagger Will automatically Authorization Send it to the server as request header information .

Step four , After the server receives the request , Will pass JwtAuthenticationTokenFilter Filter right JWT check .

Only this and nothing more , The whole process has been opened up , perfect !
Four 、 summary
To sum up , use JWT To solve the cross domain authentication in the front and rear end separation project is very smooth , This is mainly due to JSON The generality of , Can cross language ,JavaScript and Java All support ; in addition ,JWT The composition of is very simple , Very easy to transmit ; also JWT There is no need to save session information on the server side (Session), Very easy to expand .
Yes, of course , In order to ensure JWT The security of , Not in JWT Save sensitive information in , Because once the private key is compromised ,JWT It is easy to decrypt on the client ; If possible , Please use HTTPS agreement .
Reference link :
Ruan Yifeng :https://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html
Spring, summer, autumn and winter :https://segmentfault.com/a/1190000012557493
A little rain in Jiangnan :https://cloud.tencent.com/developer/article/1612175
Dearmadman:https://www.jianshu.com/p/576dbf44b2ae
mcarozheng:http://www.macrozheng.com/
Source path :
This article has been included in GitHub On the star 1.6k+ star Open source column 《Java The road to advancement of programmers 》, It is said that every excellent Java Programmers like her , Humor and wit humor 、 Easy to understand . The content includes Java Basics 、Java Concurrent programming 、Java virtual machine 、Java Enterprise development 、Java Interview and other core knowledge points . learn Java, Just recognize it Java The road to advancement of programmers .
https://github.com/itwanger/toBeBetterJavaer
star Having this warehouse means that you have become an excellent Java The potential of Engineers . You can also stamp the link below to jump to 《Java The road to advancement of programmers 》 The official website of , Start a pleasant learning journey .

Nothing makes me stay —— Except for the purpose , Even if there are roses by the shore 、 There's shade 、 There is a peaceful harbor , I'm not a boat .
kill Session? This cross domain authentication solution is really elegant ! More articles about
- JSON Web Token( abbreviation JWT) At present, the most popular cross domain authentication solution
One . The problem of cross domain authentication Internet service can not do without user authentication . The general process is as follows . 1. The user sends the user name and password to the server . 2. After the server is verified , In the current conversation (session) It holds relevant data , For example, user roles . Login time and so on . ...
- JWT token Cross domain authentication
JSON Web Token( abbreviation JWT), Is the most popular cross domain authentication solution . session Login authentication scheme : The user passes the user name from the client . Password and other information , After authentication, the server stores the information in session in , take sessio ...
- angularjs Cross domain post Solution
from :http://www.thinksaas.cn/topics/0/34/34536.html Li Lei, a front-end classmate, and Hanmeimei, a back-end classmate, developed on their own computers , When the background interface is written , Li Lei uploads the front-end code after making changes ...
- C# Advanced Series ——WebApi Cross domain problem solution :CORS
Preface : The first part summarizes WebApi The use of interface testing tools , Let's take a look at this article WebAPI Another common problem with : Cross-domain problem . This article mainly from the perspective of examples to share CORS Some details of solving cross domain problems . WebApi Series articles C# Advanced Series — ...
- thinkphp,javascript Cross domain request solution
javascript Cross domain request solution Preface For many front-end or mixed development students , We will inevitably encounter cross domain request services , such as A Site to B The site requests data and so on . Recently, I will do a site cluster project , So the specific business requires many sites ...
- C# Advanced Series ——WebApi Cross domain problem solution :CORS( Reprint )
C# Advanced Series ——WebApi Cross domain problem solution :CORS Read the directory One . The origin of cross domain problems Two . Cross domain problem solving principles 3、 ... and . Cross domain problem solving details 1. Scene description 2. Scenario test Four . summary Text Preface : The first part summarizes W ...
- Cross domain learning notes 2--WebApi Cross domain problem solution :CORS
I don't know , Let's record it here , It's for later study ... Text Preface : The first part summarizes WebApi The use of interface testing tools , Let's take a look at this article WebAPI Another common problem with : Cross-domain problem . This article mainly from the perspective of examples to share CORS Solve cross ...
- jquery Cross domain access solutions ( turn )
client “ Cross domain access ” It's always been a headache , Fortunately, there are jQuery Help , from jQuery-1.2 In the future, cross domain problems will be solved . Because I encountered cross domain problems in the project , Take this opportunity to get to the bottom of cross domain issues , Consult the relevant information and my own practice , count ...
- localstrage、cookie、session And other cross domain and cross page monitoring update issues
localstrage.cookie.session And other cross domain and cross page monitoring update issues
- cors Cross domain and jsonp Hijacking loopholes and Same origin policy and cross domain request solution
cors Cross domain and jsonp Hijacking loopholes : https://www.toutiao.com/a6759064986984645127/ Same origin policy and cross domain request solution :https://www.jianshu.co ...
Random recommendation
- mongodb Common commands
mongodb Common commands Operation on Database , And login 1 Access to database use admin 2 Add or change password db.addUser('wsc', '123') 3 View the list of users db.system.us ...
- Head First Strategic patterns of design patterns
This is the first design pattern to learn , The examples in the book are relatively complex , Reference to the online article to summarize One . Definition The strategy pattern (strategy pattern): The algorithm family is defined , Close them separately , Let's make them interchangeable , This module ...
- angular4 upgrade angular5 Problem record this.location.back()
In previous projects , Navigate back to the last route using injected Location service , Use the browser's history stack , Navigate to the previous step . That's what the official documents say However, it is upgrading to 5.2 In the version of , There is no problem when the browser is running , Print in the project ...
- With cute new look springboot Source code 03
The last section talked about quickly creating a new springboot application , as well as springboot When the autoconfiguration class works , And looked at the source code of an automatic configuration class . In this section, let's take a rough look at when a user enters a url, How to return a ...
- after RCNN The development of object detection and instance segmentation
https://mp.weixin.qq.com/s?__biz=MzA3MzI4MjgzMw==&mid=2650736740&idx=3&sn=cdce446703e69b ...
- 4~20mA
4~20mA Current output chip XTR111 Complete circuit 0-5v turn 0-20ma and 0-5v turn 4-20ma Voltage controlled constant current source circuit 4-20mA Introduction to current loop transmitter
- Ioc:Autofac Registration Concepts
Reflection Components When using reflection-based components, Autofac automatically uses the constru ...
- Windows Phone 8.1 Update Preview backup The solution to failure
We are currently using the developer preview (8.10.14219.341), I haven't been able to back it up lately text + apps + settings, The progress bar reaches 97% or 99% I'll tell you later : There was a problem ba ...
- Algorithm --- This is a summary 2—— Find the missing number , Find the biggest and the smallest , front k Big , The first k Small number
One . How to find the missing number in the array Title Description : Given a by n-1 An unordered array of integers , The original is 1 To n Different integers in , Please write a linear time algorithm to find the missing integers in the array sequence Method 1: Sum by accumulation The time complexity is O(N ...
- Sqlserver Generate scripts with data
Right click the database —> Mission —> Generation script next step Select the database to export , next step Write a data script to choose True, next step Select the table to export , next step Finally, click finish .









