diff --git a/study-project-backend/src/main/java/com/example/config/SecurityConfiguration.java b/study-project-backend/src/main/java/com/example/config/SecurityConfiguration.java index 604ac18..fbf08e2 100644 --- a/study-project-backend/src/main/java/com/example/config/SecurityConfiguration.java +++ b/study-project-backend/src/main/java/com/example/config/SecurityConfiguration.java @@ -9,6 +9,7 @@ import jakarta.servlet.http.HttpServletResponse; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; @@ -112,6 +113,10 @@ public class SecurityConfiguration { public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException { response.setCharacterEncoding("utf-8"); - response.getWriter().write(JSONObject.toJSONString(RestBean.failure(401, exception.getMessage()))); + if(exception instanceof BadCredentialsException) { + response.getWriter().write(JSONObject.toJSONString(RestBean.failure(403, exception.getMessage()))); + } else { + response.getWriter().write(JSONObject.toJSONString(RestBean.failure(401, exception.getMessage()))); + } } } diff --git a/study-project-backend/src/main/java/com/example/controller/UserController.java b/study-project-backend/src/main/java/com/example/controller/UserController.java index 568537b..7264c8a 100644 --- a/study-project-backend/src/main/java/com/example/controller/UserController.java +++ b/study-project-backend/src/main/java/com/example/controller/UserController.java @@ -5,13 +5,18 @@ import com.example.entity.user.AccountInfo; import com.example.entity.user.AccountUser; import com.example.service.UserService; import jakarta.annotation.Resource; +import jakarta.validation.constraints.Pattern; +import org.hibernate.validator.constraints.Length; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +@Validated @RestController @RequestMapping("/api/user") public class UserController { + private final String EMAIL_REGEX = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$"; + @Resource UserService service; @@ -36,4 +41,31 @@ public class UserController { public RestBean info(@SessionAttribute("account") AccountUser user){ return RestBean.success(service.userInfo(user.getId())); } + + @PostMapping("/save-email") + public RestBean saveInfo(@Pattern(regexp = EMAIL_REGEX) @RequestParam("email") String email, + @SessionAttribute("account") AccountUser user){ + if(service.saveEmail(email, user.getId())) { + user.setEmail(email); + return RestBean.success(); + } else { + return RestBean.failure(400, "邮件地址已被其他用户使用,无法修改"); + } + } + + @GetMapping("/email") + public RestBean email(@SessionAttribute("account") AccountUser user){ + return RestBean.success(user.getEmail()); + } + + @PostMapping("/save-password") + public RestBean savePassword(@Length(min = 6, max = 16) @RequestParam("old") String pass_old, + @Length(min = 6, max = 16) @RequestParam("new") String pass_new, + @SessionAttribute("account") AccountUser user){ + if (service.changePassword(pass_old, pass_new, user.getId())) { + return RestBean.success(); + } else { + return RestBean.failure(400, "原密码错误"); + } + } } diff --git a/study-project-backend/src/main/java/com/example/entity/user/AccountInfo.java b/study-project-backend/src/main/java/com/example/entity/user/AccountInfo.java index f78d6c7..0f958b2 100644 --- a/study-project-backend/src/main/java/com/example/entity/user/AccountInfo.java +++ b/study-project-backend/src/main/java/com/example/entity/user/AccountInfo.java @@ -1,11 +1,15 @@ package com.example.entity.user; +import jakarta.validation.constraints.Pattern; import lombok.Data; import org.hibernate.validator.constraints.Length; @Data public class AccountInfo { + private static final String USERNAME_REGEX = "^[a-zA-Z0-9一-龥]+$"; + int uid; + @Pattern(regexp = USERNAME_REGEX) @Length(min = 2, max = 8) String username; String sex; diff --git a/study-project-backend/src/main/java/com/example/mapper/UserMapper.java b/study-project-backend/src/main/java/com/example/mapper/UserMapper.java index 955c6f0..1ca317e 100644 --- a/study-project-backend/src/main/java/com/example/mapper/UserMapper.java +++ b/study-project-backend/src/main/java/com/example/mapper/UserMapper.java @@ -13,6 +13,9 @@ public interface UserMapper { @Select("select * from db_account where username = #{text} or email = #{text}") Account findAccountByNameOrEmail(String text); + @Select("select * from db_account where id = #{id}") + Account findAccountById(int id); + @Select("select * from db_account where username = #{text} or email = #{text}") AccountUser findAccountUserByNameOrEmail(String text); @@ -35,4 +38,10 @@ public interface UserMapper { @Select("select * from db_account_info left join db_account on id = uid where id = #{uid}") AccountInfo findInfoById(int uid); + + @Update("update db_account set email=#{email} where id=#{uid}") + void updateEmail(String email, int uid); + + @Update("update db_account set password=#{password} where id=#{uid}") + void updatePassword(String password, int uid); } diff --git a/study-project-backend/src/main/java/com/example/service/UserService.java b/study-project-backend/src/main/java/com/example/service/UserService.java index d25e379..fba7e6d 100644 --- a/study-project-backend/src/main/java/com/example/service/UserService.java +++ b/study-project-backend/src/main/java/com/example/service/UserService.java @@ -5,4 +5,6 @@ import com.example.entity.user.AccountInfo; public interface UserService { boolean saveUserInfo(AccountInfo info); AccountInfo userInfo(int uid); + boolean saveEmail(String email, int uid); + boolean changePassword(String old, String _new, int uid); } diff --git a/study-project-backend/src/main/java/com/example/service/impl/UserServiceImpl.java b/study-project-backend/src/main/java/com/example/service/impl/UserServiceImpl.java index 6b31912..df3e207 100644 --- a/study-project-backend/src/main/java/com/example/service/impl/UserServiceImpl.java +++ b/study-project-backend/src/main/java/com/example/service/impl/UserServiceImpl.java @@ -5,6 +5,7 @@ import com.example.entity.user.AccountInfo; import com.example.mapper.UserMapper; import com.example.service.UserService; import jakarta.annotation.Resource; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; @Service @@ -12,6 +13,8 @@ public class UserServiceImpl implements UserService { @Resource UserMapper mapper; + BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); + @Override public boolean saveUserInfo(AccountInfo info) { Account account = mapper.findAccountByNameOrEmail(info.getUsername()); @@ -28,4 +31,25 @@ public class UserServiceImpl implements UserService { public AccountInfo userInfo(int uid) { return mapper.findInfoById(uid); } + + @Override + public boolean saveEmail(String email, int uid) { + Account account = mapper.findAccountByNameOrEmail(email); + if(account == null) { + mapper.updateEmail(email, uid); + } else return account.getId() == uid; + return true; + } + + @Override + public boolean changePassword(String old, String _new, int uid) { + Account account = mapper.findAccountById(uid); + if (encoder.matches(old, account.getPassword())) { + String encode = encoder.encode(_new); + mapper.updatePassword(encode, uid); + return true; + } else { + return false; + } + } } diff --git a/study-project-frontend/src/components/settings/SecuritySettings.vue b/study-project-frontend/src/components/settings/SecuritySettings.vue index 1c26086..19fc3b2 100644 --- a/study-project-frontend/src/components/settings/SecuritySettings.vue +++ b/study-project-frontend/src/components/settings/SecuritySettings.vue @@ -1,13 +1,79 @@ diff --git a/study-project-frontend/src/net/index.js b/study-project-frontend/src/net/index.js index 7dc9327..fbbdb79 100644 --- a/study-project-frontend/src/net/index.js +++ b/study-project-frontend/src/net/index.js @@ -41,4 +41,13 @@ function get(url, success, failure = defaultFailure, error = defaultError) { }).catch(error) } -export { get, post } +const logout = () => { + get('/api/auth/logout', (message) => { + ElMessage.success(message) + store.auth.user = null + localStorage.removeItem('user') + router.push('/') + }) +} + +export { get, post, logout } diff --git a/study-project-frontend/src/views/IndexView.vue b/study-project-frontend/src/views/IndexView.vue index 0883db1..62857eb 100644 --- a/study-project-frontend/src/views/IndexView.vue +++ b/study-project-frontend/src/views/IndexView.vue @@ -84,8 +84,7 @@