上一篇文章主要說明了,如何用不多的代碼,經過SpringBoot的自動配置,實現一個讀取數據庫並返回數據的簡單api。java
實際應用中,一個web服務都會有用戶的註冊,登陸和鑑權等功能。git
這篇文章主要包含這幾個功能的簡單實現。web
註冊的基本實現是接收到用戶名和密碼,並把密碼加密後保存到數據庫,實現以下:redis
@RestController //定義爲rest類型的控制器 public class UserController { @Resource //注入MainUserService IMainUserService mainUserService; @PostMapping("user/register") //定義post請求 public CommonResVo<Boolean> userRegister(@RequestBody MainUser mainUser) throws Exception { //驗證用戶名是否已存在 MainUser oldUser = mainUserService.getOne(new LambdaQueryWrapper<MainUser>().eq(MainUser::getUserName, mainUser.getUserName())); if (oldUser != null) { throw new Exception("用戶已存在"); } //用戶密碼存表時,要作加密處理,能夠直接使用spring提供的DigestUtils工具類生成32位MD5字符串 String password = DigestUtils.md5DigestAsHex(mainUser.getPassword().getBytes()); mainUser.setPassword(password); mainUserService.save(mainUser); return CommonResVo.success(true); } }
{ "userName":"test2", "password":"123456", "userPhone":"13900010200" }
這裏使用session做爲用戶登陸後的驗證方式,登陸成功後會將userId寫入session中,生產中的服務基本都是集羣的,須要共享session。spring
在spring中,能夠經過配置session starter,很簡單的將session信息存儲到redis中。數據庫
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency>
spring: redis: database: 0 host: localhost port: 6379 session: store-type: redis timeout: 600s
完成上面的配置,就能夠經過redis在集羣中共享session信息了,登陸代碼以下:json
@GetMapping("user/login") public CommonResVo<Boolean> userRegister(String userName, String password, HttpSession session) throws Exception { //經過用戶名獲取用戶信息 MainUser mainUser = mainUserService.getOne(new LambdaQueryWrapper<MainUser>().eq(MainUser::getUserName, userName)); if (mainUser == null) { throw new Exception("用戶不存在"); } //對比MD5密碼 String md5Password = DigestUtils.md5DigestAsHex(password.getBytes()); if (!mainUser.getPassword().equals(md5Password)) { throw new Exception("帳號名或密碼錯誤"); } //將userId存入session中,這裏會存儲到redis中 session.setAttribute("userId", mainUser.getUserId()); return CommonResVo.success(true); }
鑑權的過程就是根據請求中的session信息,獲取userId,能夠獲取到,證實已登陸,後續根據userId獲取用戶信息進行邏輯處理。api
獲取不到,說明已過時或未登陸,提示從新登陸。cookie
web服務中,大部分接口都須要鑑權,這裏使用攔截器實現。session
經過實現HandlerInterceptor
接口定義一個攔截器,而後添加到web流程中,代碼以下:
public class LoginAuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //這裏實際是從redis中獲取到session信息 HttpSession session = request.getSession(); Integer userId = (Integer) session.getAttribute("userId"); if (userId == null) { authFailOutput(response, "登陸信息不存在,請從新登陸"); return false; } return true; } /** * json輸出 * * @param response * @throws IOException */ private void authFailOutput(HttpServletResponse response, String msg) throws IOException { response.setContentType("application/json;charset=UTF-8"); PrintWriter out = response.getWriter(); ObjectMapper objectMapper = new ObjectMapper(); out.write(objectMapper.writeValueAsString(CommonResVo.fail(400, msg))); out.flush(); } }
@Configuration public class Interceptor implements WebMvcConfigurer { @Bean LoginAuthInterceptor loginAuthInterceptor() { return new LoginAuthInterceptor(); } @Override public void addInterceptors(InterceptorRegistry registry) { // 添加一個攔截器,排除登陸url registry.addInterceptor(loginAuthInterceptor()) .excludePathPatterns("/user/login"); } }
一般建立session後,sessionId會保存在cookies裏面,默認名是SESSION,用於以後的每次請求。這裏要注意,cookies保存的sessionId默認是base64編碼過的,因此和程序中使用session.getId()
獲取到的會不一樣。
若是不想使用系統默認的cookie名稱保存sessionId,能夠經過修改application.yml的配置實現自定名稱,示例以下:
server: port: 8999 servlet: session: cookie: name: myjsessionid //自定義的session名稱
這樣系統中就會使用myjsessionid保存和解析session信息。
源碼地址:https://gitee.com/dothetrick/...
以上內容屬我的學習總結,若有不當之處,歡迎在評論中指正