上一篇文章主要说明了,如何用不多的代码,经过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/...
以上内容属我的学习总结,若有不当之处,欢迎在评论中指正