============= 后端_登录退出 ============= 1 添加账户实体类 /src/main/java/com/weihome/barblog/entity/Account.java: /** * 账户实体类 */ @Data public class Account implements Serializable { @NotBlank(message = "昵称不能为空") private String username; @NotBlank(message = "密码不能为空") private String password; } 2 添加账户控制器类 /** * 账户控制器类 */ @RestController public class AccountController { @Autowired UserService userService; @Autowired JwtUtils jwtUtils; /** * 登录 */ @PostMapping("/login") public Result login( @Validated @RequestBody Account account, HttpServletResponse response) { // 根据用户名从数据库中读取用户信息 User user = userService.getOne( new QueryWrapper().eq("username", account.getUsername())); Assert.notNull(user, "用户不存在"); // 验证密码(MD5摘要) if(!user.getPassword().equals( SecureUtil.md5(account.getPassword()))) return Result.error("密码不正确"); // 根据用户ID生成令牌并加入到响应头中 String token = jwtUtils.generateToken(user.getId()); response.setHeader("Authorization", token); response.setHeader("Access-control-Expose-Headers", "Authorization"); // 响应成功 return Result.ok(MapUtil.builder() .put("id", user.getId()) .put("username", user.getUsername()) .put("avatar", user.getAvatar()) .put("email", user.getEmail()) .map()); } /** * 退出 */ @RequiresAuthentication @GetMapping("/logout") public Result logout() { SecurityUtils.getSubject().logout(); return Result.ok(null); } } 3 添加针对Assert断言的无效参数异常处理 /src/main/java/com/weihome/barblog/common/GlobalExcepitonHandler.java: ... public class GlobalExcepitonHandler { ... /** * 无效参数异常 */ @ResponseStatus(HttpStatus.BAD_REQUEST) // 400 @ExceptionHandler(value = IllegalArgumentException.class) public Result handler(IllegalArgumentException e) { log.error("无效参数异常", e); return Result.error(e.getMessage()); } ... } 4 运行测试 执行BarblogApplication.main()... Postman: POST localhost:8081/login Body raw/JSON { "username": "kitty", "password": "123456" } ---------------------------- { "code": 400, "message": "用户不存在", "data": null } Postman: POST localhost:8081/login Body raw/JSON { "username": "bear", "password": "123456" } ---------------------------- { "code": 400, "message": "密码不正确", "data": null } Postman: POST localhost:8081/login Body raw/JSON { "username": "bear", "password": "111111" } ---------------------------- { "code": 200, "message": "操作成功", "data": { "id": 1, "avatar": "bear.png", "email": "johnmin74@hotmail.com", "username": "bear" } } Headers ... Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwiaWF0IjoxNjQ4MDkwMzEzLCJleHAiOjE2NDg2OTUxMTN9.mKL47JVwZlajifw9p8y9hD-X_60ib-t_zARHGsG8CGGD_wBCJCIrLhqO8ldYhWxeI_WNkdJGvCyvSC6z3Mdv8w ... ^ | 令牌字符串 Postman: GET localhost:8081/user/index Headers Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwiaWF0IjoxNjQ4MDkwMzEzLCJleHAiOjE2NDg2OTUxMTN9.mKL47JVwZlajifw9p8y9hD-X_60ib-t_zARHGsG8CGGD_wBCJCIrLhqO8ldYhWxeI_WNkdJGvCyvSC6z3Mdv8w ---------------------------- { "code": 200, "message": "操作成功", "data": { "id": 1, "username": "bear", "avatar": "bear.png", "email": "johnmin74@hotmail.com", "password": "96e79218965eb72c92a549dd5a330112", "status": 0, "created": "2022-03-22T12:00:00", "lastLogin": null } } Postman: GET localhost:8081/logout Headers Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxIiwiaWF0IjoxNjQ4MDkwMzEzLCJleHAiOjE2NDg2OTUxMTN9.mKL47JVwZlajifw9p8y9hD-X_60ib-t_zARHGsG8CGGD_wBCJCIrLhqO8ldYhWxeI_WNkdJGvCyvSC6z3Mdv8w ---------------------------- { "code": 200, "message": "操作成功", "data": null } 删除Cookie。 Postman: GET localhost:8081/user/index ---------------------------- { "code": 401, "message": "The current Subject is not authenticated. Access denied.", "data": null }