| | |
| | | } |
| | | ``` |
| | | |
| | | ## 3. è·åç¨æ·ä¿¡æ¯æ¥å£ |
| | | ## 3. éåºç»å½æ¥å£ |
| | | |
| | | ### æ¥å£ä¿¡æ¯ |
| | | - 请æ±è·¯å¾ï¼`/api/users/logout` |
| | | - è¯·æ±æ¹æ³ï¼POST |
| | | - 请æ±å¤´ï¼éè¦æºå¸¦ token |
| | | |
| | | ### æµè¯ç¨ä¾ |
| | | |
| | | #### æååºæ¯ |
| | | 1. æ£å¸¸éåºç»å½ |
| | | - 请æ±å¤´ï¼ |
| | | ``` |
| | | token: eyJhbGciOiJIUzI1NiJ9... |
| | | ``` |
| | | - 颿ååºï¼ |
| | | ```json |
| | | { |
| | | "code": 200, |
| | | "message": "éåºç»å½æå", |
| | | "data": null |
| | | } |
| | | ``` |
| | | |
| | | #### å¤±è´¥åºæ¯ |
| | | 1. æªæºå¸¦ token |
| | | - 请æ±å¤´ï¼æ token |
| | | - 颿ååºï¼ |
| | | ```json |
| | | { |
| | | "code": 400, |
| | | "message": "æªç»å½ç¶æ", |
| | | "data": null |
| | | } |
| | | ``` |
| | | |
| | | 2. token æ ææå·²è¿æ |
| | | - 请æ±å¤´ï¼ |
| | | ``` |
| | | token: invalid_token |
| | | ``` |
| | | - 颿ååºï¼ |
| | | ```json |
| | | { |
| | | "code": 401, |
| | | "message": "tokenæ ææå·²è¿æ", |
| | | "data": null |
| | | } |
| | | ``` |
| | | |
| | | ## 4. è·åç¨æ·ä¿¡æ¯æ¥å£ |
| | | |
| | | ### æ¥å£ä¿¡æ¯ |
| | | - 请æ±è·¯å¾ï¼`/api/users/info` |
| | |
| | | 3. ç¨æ·ä¿¡æ¯æ¥å£éè¦ææç JWT token |
| | | 4. å¯ç å¨ä¼ è¾è¿ç¨ä¸åºè¯¥ä½¿ç¨ HTTPS å å¯ |
| | | 5. å»ºè®®å¨æµè¯ç¯å¢ä¸ä½¿ç¨æµè¯æ°æ®åº |
| | | 6. æµè¯æ¶æ³¨ææ¸
çæµè¯æ°æ®ï¼é¿å
å½±åå
¶ä»æµè¯ç¨ä¾ |
| | | 6. æµè¯æ¶æ³¨ææ¸
çæµè¯æ°æ®ï¼é¿å
å½±åå
¶ä»æµè¯ç¨ä¾ |
| | | 7. éåºç»å½åç token ä¼è¢«å å
¥é»ååï¼æ æ³åæ¬¡ä½¿ç¨ |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.weiwojc.config; |
| | | |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.web.cors.CorsConfiguration; |
| | | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; |
| | | import org.springframework.web.filter.CorsFilter; |
| | | |
| | | @Configuration |
| | | public class CorsConfig { |
| | | |
| | | @Bean |
| | | public CorsFilter corsFilter() { |
| | | UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); |
| | | CorsConfiguration config = new CorsConfiguration(); |
| | | |
| | | // å
许跨åçæºï¼è¿é设置为å
è®¸æææº |
| | | config.addAllowedOriginPattern("*"); |
| | | // å
许跨åç请æ±å¤´ |
| | | config.addAllowedHeader("*"); |
| | | // å
许跨åçè¯·æ±æ¹æ³ |
| | | config.addAllowedMethod("*"); |
| | | // å
许æºå¸¦è®¤è¯ä¿¡æ¯ï¼tokenï¼ |
| | | config.setAllowCredentials(true); |
| | | // æ´é²ååºå¤´ |
| | | config.addExposedHeader("*"); |
| | | // 设置跨å请æ±çæææï¼åä½ä¸ºç§ |
| | | config.setMaxAge(3600L); |
| | | |
| | | source.registerCorsConfiguration("/**", config); |
| | | return new CorsFilter(source); |
| | | } |
| | | } |
| | |
| | | import org.springframework.security.crypto.password.PasswordEncoder; |
| | | import org.springframework.security.web.SecurityFilterChain; |
| | | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; |
| | | import org.springframework.web.cors.CorsConfiguration; |
| | | import org.springframework.web.cors.CorsConfigurationSource; |
| | | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; |
| | | |
| | | @Configuration |
| | | @EnableWebSecurity |
| | |
| | | @Bean |
| | | public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { |
| | | http |
| | | .cors(cors -> cors.configurationSource(corsConfigurationSource())) |
| | | .csrf(AbstractHttpConfigurer::disable) |
| | | .sessionManagement(session -> session |
| | | .sessionCreationPolicy(SessionCreationPolicy.STATELESS)) |
| | |
| | | } |
| | | |
| | | @Bean |
| | | public CorsConfigurationSource corsConfigurationSource() { |
| | | CorsConfiguration configuration = new CorsConfiguration(); |
| | | configuration.addAllowedOriginPattern("*"); |
| | | configuration.addAllowedMethod("*"); |
| | | configuration.addAllowedHeader("*"); |
| | | configuration.setAllowCredentials(true); |
| | | configuration.addExposedHeader("*"); |
| | | configuration.setMaxAge(3600L); |
| | | |
| | | UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); |
| | | source.registerCorsConfiguration("/**", configuration); |
| | | return source; |
| | | } |
| | | |
| | | @Bean |
| | | public PasswordEncoder passwordEncoder() { |
| | | return new BCryptPasswordEncoder(); |
| | | } |
| | |
| | | import com.weiwojc.model.entity.User; |
| | | import com.weiwojc.service.UserService; |
| | | import com.weiwojc.utils.JwtUtils; |
| | | import com.weiwojc.utils.TokenBlacklistManager; |
| | | import jakarta.servlet.http.HttpServletRequest; |
| | | import jakarta.validation.Valid; |
| | | import lombok.RequiredArgsConstructor; |
| | |
| | | |
| | | private final UserService userService; |
| | | private final JwtUtils jwtUtils; |
| | | private final TokenBlacklistManager tokenBlacklistManager; |
| | | |
| | | @PostMapping("/register") |
| | | public Result<User> register(@Valid @RequestBody UserRegisterDTO registerDTO) { |
| | |
| | | return Result.success("ç»å½æå", token); |
| | | } |
| | | |
| | | @PostMapping("/logout") |
| | | public Result<String> logout(HttpServletRequest request) { |
| | | String token = request.getHeader("token"); |
| | | if (token == null || token.isEmpty()) { |
| | | return Result.error("æªç»å½ç¶æ"); |
| | | } |
| | | |
| | | // éªè¯tokenæ¯å¦ææ |
| | | if (!jwtUtils.validateToken(token)) { |
| | | return Result.unauthorized("tokenæ ææå·²è¿æ"); |
| | | } |
| | | |
| | | // å°tokenå å
¥é»åå |
| | | tokenBlacklistManager.addToBlacklist(token); |
| | | return Result.success("éåºç»å½æå"); |
| | | } |
| | | |
| | | @GetMapping("/info") |
| | | public Result<User> getUserInfo(HttpServletRequest request) { |
| | | String token = request.getHeader("token"); |