diff --git a/sky-server/src/main/java/com/sky/config/WebMvcConfiguration.java b/sky-server/src/main/java/com/sky/config/WebMvcConfiguration.java index c4b4b39..7bf00db 100644 --- a/sky-server/src/main/java/com/sky/config/WebMvcConfiguration.java +++ b/sky-server/src/main/java/com/sky/config/WebMvcConfiguration.java @@ -3,6 +3,7 @@ package com.sky.config; import ch.qos.logback.classic.pattern.MessageConverter; import com.fasterxml.jackson.databind.ObjectMapper; import com.sky.interceptor.JwtTokenAdminInterceptor; +import com.sky.interceptor.JwtTokenUserInterceptor; import com.sky.json.JacksonObjectMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -32,6 +33,8 @@ public class WebMvcConfiguration extends WebMvcConfigurationSupport { @Resource private JwtTokenAdminInterceptor jwtTokenAdminInterceptor; + @Resource + private JwtTokenUserInterceptor jwtTokenUserInterceptor; /** * 注册自定义拦截器 @@ -43,11 +46,17 @@ public class WebMvcConfiguration extends WebMvcConfigurationSupport { registry.addInterceptor(jwtTokenAdminInterceptor) .addPathPatterns("/admin/**") .excludePathPatterns("/admin/employee/login"); + + registry.addInterceptor(jwtTokenAdminInterceptor) + .addPathPatterns("/user/**") + .excludePathPatterns("/user/user/login") + .excludePathPatterns("/user/shop/status"); } /** * 通过knife4j生成接口文档 * 管理后台文档 + * * @return Docket */ @Bean @@ -69,6 +78,7 @@ public class WebMvcConfiguration extends WebMvcConfigurationSupport { /** * 通过knife4j生成接口文档 * 用户前台文档 + * * @return Docket */ @Bean @@ -108,6 +118,6 @@ public class WebMvcConfiguration extends WebMvcConfigurationSupport { log.info("扩展消息转换器..."); MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setObjectMapper(new JacksonObjectMapper()); - converters.add(0,converter); + converters.add(0, converter); } } diff --git a/sky-server/src/main/java/com/sky/controller/user/ShopController.java b/sky-server/src/main/java/com/sky/controller/user/ShopController.java index eb12b4f..9b76a1c 100644 --- a/sky-server/src/main/java/com/sky/controller/user/ShopController.java +++ b/sky-server/src/main/java/com/sky/controller/user/ShopController.java @@ -6,7 +6,6 @@ import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -22,7 +21,7 @@ public class ShopController { private RedisTemplate redisTemplate; @ApiOperation("设置店铺营业状态") - @GetMapping("/status") + @GetMapping("status") public Result setStatus() { Integer status = (Integer) redisTemplate.opsForValue().get(KEY); log.info("设置店铺营业状态:{}", status == 1 ? "营业中" : "打样中"); diff --git a/sky-server/src/main/java/com/sky/controller/user/UserController.java b/sky-server/src/main/java/com/sky/controller/user/UserController.java new file mode 100644 index 0000000..c19120e --- /dev/null +++ b/sky-server/src/main/java/com/sky/controller/user/UserController.java @@ -0,0 +1,57 @@ +package com.sky.controller.user; + +import com.sky.constant.JwtClaimsConstant; +import com.sky.dto.UserLoginDTO; +import com.sky.entity.User; +import com.sky.mapper.UserMapper; +import com.sky.properties.JwtProperties; +import com.sky.result.Result; +import com.sky.service.UserService; +import com.sky.utils.JwtUtil; +import com.sky.vo.UserLoginVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.HashMap; + +@RestController +@RequestMapping("/user/user") +@Api(tags = "C端用户相关接口") +@Slf4j +public class UserController { + @Resource + private UserService userService; + @Resource + private JwtProperties jwtProperties; + + + /** + * 微信登录 + * + * @param userLoginDTO 用户传过来的数据 + * @return 结果 + */ + @ApiOperation("微信登录") + @PostMapping("/login") + public Result login(@RequestBody UserLoginDTO userLoginDTO) { + log.info("微信登录:{}", userLoginDTO.getCode()); + // 微信登录 + User user = userService.wxLogin(userLoginDTO); + // 为用户生成jwt令牌 + HashMap claims = new HashMap<>(); + claims.put(JwtClaimsConstant.USER_ID, user.getId()); + String token = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims); + // 封装返回对象 + UserLoginVO userLoginVO = UserLoginVO.builder() + .id(user.getId()) + .openid(user.getOpenid()) + .token(token).build(); + return Result.success(userLoginVO); + } +} diff --git a/sky-server/src/main/java/com/sky/interceptor/JwtTokenUserInterceptor.java b/sky-server/src/main/java/com/sky/interceptor/JwtTokenUserInterceptor.java new file mode 100644 index 0000000..5a532ae --- /dev/null +++ b/sky-server/src/main/java/com/sky/interceptor/JwtTokenUserInterceptor.java @@ -0,0 +1,61 @@ +package com.sky.interceptor; + +import com.sky.constant.JwtClaimsConstant; +import com.sky.context.BaseContext; +import com.sky.properties.JwtProperties; +import com.sky.utils.JwtUtil; +import io.jsonwebtoken.Claims; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * jwt令牌校验的拦截器 + */ +@Component +@Slf4j +public class JwtTokenUserInterceptor implements HandlerInterceptor { + + @Resource + private JwtProperties jwtProperties; + + /** + * 校验jwt + * + * @param request HttpServletRequest + * @param response HttpServletResponse + * @param handler Object + * @return boolean + * @throws Exception Exception + */ + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + //判断当前拦截到的是Controller的方法还是其他资源 + if (!(handler instanceof HandlerMethod)) { + //当前拦截到的不是动态方法,直接放行 + return true; + } + + //1、从请求头中获取令牌 + String token = request.getHeader(jwtProperties.getUserTokenName()); + + //2、校验令牌 + try { + log.info("jwt校验:{}", token); + Claims claims = JwtUtil.parseJWT(jwtProperties.getUserSecretKey(), token); + Long userId = Long.valueOf(claims.get(JwtClaimsConstant.USER_ID).toString()); + log.info("当前用户id:{}", userId); + BaseContext.setCurrentId(userId); + //3、通过,放行 + return true; + } catch (Exception ex) { + //4、不通过,响应401状态码 + response.setStatus(401); + return false; + } + } +} diff --git a/sky-server/src/main/java/com/sky/mapper/UserMapper.java b/sky-server/src/main/java/com/sky/mapper/UserMapper.java new file mode 100644 index 0000000..56a944e --- /dev/null +++ b/sky-server/src/main/java/com/sky/mapper/UserMapper.java @@ -0,0 +1,21 @@ +package com.sky.mapper; + +import com.sky.entity.User; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface UserMapper { + + /** + * 根据用户id查询用户 + * @param openid String + * @return User + */ + User getByOpenid(String openid); + + /** + * 如果为新用户自动完成注册 + * @param user User + */ + void insert(User user); +} diff --git a/sky-server/src/main/java/com/sky/service/UserService.java b/sky-server/src/main/java/com/sky/service/UserService.java new file mode 100644 index 0000000..c18021c --- /dev/null +++ b/sky-server/src/main/java/com/sky/service/UserService.java @@ -0,0 +1,13 @@ +package com.sky.service; + +import com.sky.dto.UserLoginDTO; +import com.sky.entity.User; + +public interface UserService { + /** + * 微信登录 + * @param userLoginDTO UserLoginDTO + * @return User + */ + User wxLogin(UserLoginDTO userLoginDTO); +} diff --git a/sky-server/src/main/java/com/sky/service/impl/UserServiceImpl.java b/sky-server/src/main/java/com/sky/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..f3e295c --- /dev/null +++ b/sky-server/src/main/java/com/sky/service/impl/UserServiceImpl.java @@ -0,0 +1,71 @@ +package com.sky.service.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.sky.constant.MessageConstant; +import com.sky.dto.UserLoginDTO; +import com.sky.entity.User; +import com.sky.exception.LoginFailedException; +import com.sky.mapper.UserMapper; +import com.sky.properties.WeChatProperties; +import com.sky.service.UserService; +import com.sky.utils.HttpClientUtil; +import org.apache.http.client.HttpClient; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.HashMap; + +@Service +public class UserServiceImpl implements UserService { + public static final String WX_LOGIN = "https://api.weixin.qq.com/sns/jscode2session"; + @Resource + private WeChatProperties weChatProperties; + @Resource + private UserMapper userMapper; + + /** + * 微信登录 + * + * @param userLoginDTO UserLoginDTO + * @return User + */ + @Override + public User wxLogin(UserLoginDTO userLoginDTO) { + String openid = getOpenid(userLoginDTO.getCode()); + // 判断openid是否为空,如果为空表示登录失败,排出业务异常 + if (openid == null) { + throw new LoginFailedException(MessageConstant.LOGIN_FAILED); + } + // 判断当前用户是否为新用户 + User user = userMapper.getByOpenid(openid); + // 如果为新用户自动完成注册 + if (user == null) { + user = User.builder() + .openid(openid) + .createTime(LocalDateTime.now()) + .build(); + userMapper.insert(user); + } + // 返回这个用户对象 + return user; + } + + /** + * 调用微信接口服务 + * @param code Code + * @return String + */ + private String getOpenid(String code) { + // 调用微信接口服务,获得当前用户openiid + HashMap map = new HashMap<>(); + map.put("appid", weChatProperties.getAppid()); + map.put("secret", weChatProperties.getSecret()); + map.put("js_code", code); + map.put("grant_type", "authorization_code"); + String json = HttpClientUtil.doGet(WX_LOGIN, map); + JSONObject jsonObject = JSON.parseObject(json); + return jsonObject.getString("openid"); + } +} diff --git a/sky-server/src/main/resources/application-dev.yml b/sky-server/src/main/resources/application-dev.yml index d4516a7..0f6b0b5 100644 --- a/sky-server/src/main/resources/application-dev.yml +++ b/sky-server/src/main/resources/application-dev.yml @@ -16,3 +16,6 @@ sky: port: 6378 password: "02120212" database: 1 + wechat: + appid: wx18e5556d7539757b + secret: ac06f1c49f90a2ed69f1a946d4981833 \ No newline at end of file diff --git a/sky-server/src/main/resources/application.yml b/sky-server/src/main/resources/application.yml index 953e55c..c244499 100644 --- a/sky-server/src/main/resources/application.yml +++ b/sky-server/src/main/resources/application.yml @@ -48,9 +48,15 @@ sky: admin-ttl: 66666666666666 # 设置前端传递过来的令牌名称 admin-token-name: token + user-secret-key: itheima + user-ttl: 66666666666666 + user-token-name: authentication minio: endpointUrl: ${sky.minio.endpointUrl} accessKey: ${sky.minio.accessKey} secretKey: ${sky.minio.secretKey} bucket-name: ${sky.minio.bucket-name} + wechat: + appid: ${sky.wechat.appid} + secret: ${sky.wechat.secret} \ No newline at end of file diff --git a/sky-server/src/main/resources/mapper/UserMapper.xml b/sky-server/src/main/resources/mapper/UserMapper.xml new file mode 100644 index 0000000..edf7f29 --- /dev/null +++ b/sky-server/src/main/resources/mapper/UserMapper.xml @@ -0,0 +1,17 @@ + + + + + + + insert into user (openid, name, phone, sex, id_number, avatar, create_time) + values (#{openid}, #{name}, #{phone}, #{sex}, #{idNumber}, #{avatar}, #{createTime}); + + + + +