From 4c51872e4e0e809ea10272bf7627fe51acc9e508 Mon Sep 17 00:00:00 2001 From: sjl <15627915168@163.com> Date: Fri, 26 Feb 2021 13:53:04 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0H5=E7=AB=AF=E6=B3=A8=E5=86=8C?= =?UTF-8?q?=E3=80=81=E7=99=BB=E5=BD=95=E3=80=81=E9=80=80=E5=87=BA=EF=BC=8C?= =?UTF-8?q?=E6=94=AF=E4=BB=98=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shop/api/controller/PayController.java | 21 +++ .../shop/api/controller/UserController.java | 63 ++++--- .../controller/UserRegisterController.java | 72 ++++++++ .../api/security/AuthenticationToken.java | 95 +++++++++++ .../api/security/WebAuthenticationToken.java | 27 +++ .../WebLoginAuthenticationFilter.java | 153 +++++++++++++++++ .../YamiAuthenticationProcessingFilter.java | 154 ++++++++++++++++++ .../api/security/YamiUserServiceImpl.java | 25 ++- .../shop/bean/param/UserRegisterParam.java | 35 ++++ .../com/yami/shop/security/enums/App.java | 15 +- .../yami/shop/security/service/YamiUser.java | 11 ++ .../service/YamiUserDetailsService.java | 8 + .../shop/security/util/YamiTokenServices.java | 2 +- .../java/com/yami/shop/dao/UserMapper.java | 2 + .../com/yami/shop/service/UserService.java | 3 + .../shop/service/impl/UserServiceImpl.java | 25 ++- .../src/main/resources/mapper/UserMapper.xml | 6 +- 17 files changed, 682 insertions(+), 35 deletions(-) create mode 100644 yami-shop-api/src/main/java/com/yami/shop/api/controller/UserRegisterController.java create mode 100644 yami-shop-api/src/main/java/com/yami/shop/api/security/AuthenticationToken.java create mode 100644 yami-shop-api/src/main/java/com/yami/shop/api/security/WebAuthenticationToken.java create mode 100644 yami-shop-api/src/main/java/com/yami/shop/api/security/WebLoginAuthenticationFilter.java create mode 100644 yami-shop-api/src/main/java/com/yami/shop/api/security/YamiAuthenticationProcessingFilter.java create mode 100644 yami-shop-bean/src/main/java/com/yami/shop/bean/param/UserRegisterParam.java diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/controller/PayController.java b/yami-shop-api/src/main/java/com/yami/shop/api/controller/PayController.java index 90e8dfc..b41dcc1 100644 --- a/yami-shop-api/src/main/java/com/yami/shop/api/controller/PayController.java +++ b/yami-shop-api/src/main/java/com/yami/shop/api/controller/PayController.java @@ -10,6 +10,7 @@ package com.yami.shop.api.controller; +import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult; import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; import com.github.binarywang.wxpay.constant.WxPayConstants; @@ -32,6 +33,8 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.util.List; + @RestController @RequestMapping("/p/order") @Api(tags = "订单接口") @@ -69,4 +72,22 @@ public class PayController { return ResponseEntity.ok(wxMiniPayService.createOrder(orderRequest)); } + + /** + * 普通支付接口 + */ + @PostMapping("/normalPay") + @ApiOperation(value = "根据订单号进行支付", notes = "根据订单号进行支付") + @SneakyThrows + public ResponseEntity normalPay(@RequestBody PayParam payParam) { + + YamiUser user = SecurityUtils.getUser(); + String userId = user.getUserId(); + PayInfoDto pay = payService.pay(userId, payParam); + + // 根据内部订单号更新order settlement + payService.paySuccess(pay.getPayNo(), ""); + + return ResponseEntity.ok(true); + } } diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/controller/UserController.java b/yami-shop-api/src/main/java/com/yami/shop/api/controller/UserController.java index 7841800..33f1ac2 100644 --- a/yami-shop-api/src/main/java/com/yami/shop/api/controller/UserController.java +++ b/yami-shop-api/src/main/java/com/yami/shop/api/controller/UserController.java @@ -18,6 +18,7 @@ import com.yami.shop.security.util.SecurityUtils; import lombok.AllArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; +import org.springframework.security.oauth2.provider.token.ConsumerTokenServices; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -34,6 +35,8 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import ma.glasnost.orika.MapperFacade; +import javax.servlet.http.HttpServletRequest; + @RestController @RequestMapping("/p/user") @Api(tags="用户接口") @@ -41,33 +44,45 @@ import ma.glasnost.orika.MapperFacade; public class UserController { private final UserService userService; - + private final MapperFacade mapperFacade; private final CacheManagerUtil cacheManagerUtil; - /** - * 查看用户接口 - */ - @GetMapping("/userInfo") - @ApiOperation(value="查看用户信息", notes="根据用户ID(userId)获取用户信息") - public ResponseEntity userInfo() { - String userId = SecurityUtils.getUser().getUserId(); - User user = userService.getById(userId); - UserDto userDto = mapperFacade.map(user, UserDto.class); - return ResponseEntity.ok(userDto); - } - - @PutMapping("/setUserInfo") - @ApiOperation(value="设置用户信息", notes="设置用户信息") - public ResponseEntity setUserInfo(@RequestBody UserInfoParam userInfoParam) { - String userId = SecurityUtils.getUser().getUserId(); - User user = new User(); - user.setUserId(userId); - user.setPic(userInfoParam.getAvatarUrl()); - user.setNickName(EmojiUtil.toAlias(userInfoParam.getNickName())); - userService.updateById(user); + + private final ConsumerTokenServices consumerTokenServices; + /** + * 查看用户接口 + */ + @GetMapping("/userInfo") + @ApiOperation(value="查看用户信息", notes="根据用户ID(userId)获取用户信息") + public ResponseEntity userInfo() { + String userId = SecurityUtils.getUser().getUserId(); + User user = userService.getById(userId); + UserDto userDto = mapperFacade.map(user, UserDto.class); + return ResponseEntity.ok(userDto); + } + + @PutMapping("/setUserInfo") + @ApiOperation(value="设置用户信息", notes="设置用户信息") + public ResponseEntity setUserInfo(@RequestBody UserInfoParam userInfoParam) { + String userId = SecurityUtils.getUser().getUserId(); + User user = new User(); + user.setUserId(userId); + user.setPic(userInfoParam.getAvatarUrl()); + user.setNickName(EmojiUtil.toAlias(userInfoParam.getNickName())); + userService.updateById(user); String cacheKey = App.MINI.value() + StrUtil.COLON + SecurityUtils.getUser().getBizUserId(); cacheManagerUtil.evictCache("yami_user", cacheKey); - return ResponseEntity.ok(null); - } + return ResponseEntity.ok(null); + } + + /** + * 退出登录,并清除redis中的token + **/ + @GetMapping("/logout") + public Boolean removeToken(HttpServletRequest httpRequest){ + String authorization = httpRequest.getHeader("authorization"); + String token = authorization.replace("bearer", ""); + return consumerTokenServices.revokeToken(token); + } } diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/controller/UserRegisterController.java b/yami-shop-api/src/main/java/com/yami/shop/api/controller/UserRegisterController.java new file mode 100644 index 0000000..2ae02ec --- /dev/null +++ b/yami-shop-api/src/main/java/com/yami/shop/api/controller/UserRegisterController.java @@ -0,0 +1,72 @@ +package com.yami.shop.api.controller; + + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.yami.shop.api.security.AuthenticationToken; +import com.yami.shop.bean.model.User; +import com.yami.shop.bean.param.UserRegisterParam; +import com.yami.shop.common.exception.YamiShopBindException; +import com.yami.shop.common.util.IPHelper; +import com.yami.shop.security.handler.LoginAuthSuccessHandler; +import com.yami.shop.security.model.AppConnect; +import com.yami.shop.security.service.YamiUserDetailsService; +import com.yami.shop.service.UserService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.AllArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.oauth2.provider.token.ConsumerTokenServices; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.util.Date; + +/** + * 用户信息 + * + * @author SJL + */ +@RestController +@RequestMapping("/user") +@Api(tags = "用户注册相关接口") +@AllArgsConstructor +public class UserRegisterController { + + private final UserService userService; + + private final PasswordEncoder passwordEncoder; + + @PostMapping("/register") + @ApiOperation(value = "注册", notes = "用户注册或绑定手机号接口") + public ResponseEntity register(@Valid @RequestBody UserRegisterParam userRegisterParam) { + userRegisterParam.setPassword(passwordEncoder.encode(userRegisterParam.getPassword())); + return ResponseEntity.ok(userService.insertUser(userRegisterParam)); + } + + + @PutMapping("/updatePwd") + @ApiOperation(value = "修改密码", notes = "修改密码") + public ResponseEntity updatePwd(@Valid @RequestBody UserRegisterParam userRegisterParam) { + User user = userService.getOne(new LambdaQueryWrapper().eq(User::getUserMobile, userRegisterParam.getUserMail())); + if (user == null) { + // 无法获取用户信息 + throw new YamiShopBindException("yami.user.no.exist"); + } + if (StrUtil.isBlank(userRegisterParam.getPassword())) { + // 新密码不能为空 + throw new YamiShopBindException("yami.user.password.no.exist"); + } + if (StrUtil.equals(passwordEncoder.encode(userRegisterParam.getPassword()), user.getLoginPassword())) { + // 新密码不能与原密码相同 + throw new YamiShopBindException("yami.user.password.check"); + } + user.setModifyTime(new Date()); + user.setLoginPassword(passwordEncoder.encode(userRegisterParam.getPassword())); + userService.updateById(user); + return ResponseEntity.ok().build(); + } +} diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/security/AuthenticationToken.java b/yami-shop-api/src/main/java/com/yami/shop/api/security/AuthenticationToken.java new file mode 100644 index 0000000..644c48d --- /dev/null +++ b/yami-shop-api/src/main/java/com/yami/shop/api/security/AuthenticationToken.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved. + * + * https://www.gz-yami.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ + +package com.yami.shop.api.security; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.CredentialsContainer; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Collection; + +/** + * 自定义AbstractAuthenticationToken, + * @author SJL + */ +@Getter +@Setter +public class AuthenticationToken implements Authentication, + CredentialsContainer { + + private Collection authorities; + private UserDetails details; + + /** + * 用户名 + */ + protected String principal; + + /** + * 密码 + */ + protected Object credentials; + + /** + * uuid,现在用于验证码 + */ + private String sessionUUID; + + private boolean authenticated = false; + + public void setDetails(UserDetails details) { + this.details = details; + } + + + @Override + public Collection getAuthorities() { + return details.getAuthorities(); + } + + + @Override + public Object getDetails() { + return details; + } + + @Override + public boolean isAuthenticated() { + return authenticated; + } + + @Override + public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { + this.authenticated = isAuthenticated; + } + + @Override + public String getName() { + return details.getUsername(); + } + + @Override + public void eraseCredentials() { + eraseSecret(getCredentials()); + eraseSecret(getPrincipal()); + eraseSecret(details); + } + + private void eraseSecret(Object secret) { + if (secret instanceof CredentialsContainer) { + ((CredentialsContainer) secret).eraseCredentials(); + } + } + +} diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/security/WebAuthenticationToken.java b/yami-shop-api/src/main/java/com/yami/shop/api/security/WebAuthenticationToken.java new file mode 100644 index 0000000..64f4738 --- /dev/null +++ b/yami-shop-api/src/main/java/com/yami/shop/api/security/WebAuthenticationToken.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved. + * + * https://www.gz-yami.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ + +package com.yami.shop.api.security; + +import com.yami.shop.security.token.MyAuthenticationToken; +import lombok.NoArgsConstructor; +import org.springframework.security.core.userdetails.UserDetails; + +/** + * H5端Token + */ +@NoArgsConstructor +public class WebAuthenticationToken extends MyAuthenticationToken { + + + public WebAuthenticationToken(UserDetails principal, Object credentials) { + super(principal, credentials, principal.getAuthorities()); + } +} diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/security/WebLoginAuthenticationFilter.java b/yami-shop-api/src/main/java/com/yami/shop/api/security/WebLoginAuthenticationFilter.java new file mode 100644 index 0000000..e431408 --- /dev/null +++ b/yami-shop-api/src/main/java/com/yami/shop/api/security/WebLoginAuthenticationFilter.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved. + * + * https://www.gz-yami.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ + +package com.yami.shop.api.security; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; +import cn.hutool.core.util.BooleanUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.extra.servlet.ServletUtil; +import com.yami.shop.common.util.Json; +import com.yami.shop.common.util.RedisUtil; +import com.yami.shop.security.constants.SecurityConstants; +import com.yami.shop.security.enums.App; +import com.yami.shop.security.exception.BadCredentialsExceptionBase; +import com.yami.shop.security.exception.ImageCodeNotMatchExceptionBase; +import com.yami.shop.security.exception.UsernameNotFoundExceptionBase; +import com.yami.shop.security.exception.WxErrorExceptionBase; +import com.yami.shop.security.model.AppConnect; +import com.yami.shop.security.service.YamiUser; +import com.yami.shop.security.service.YamiUserDetailsService; +import com.yami.shop.security.token.MyAuthenticationToken; +import lombok.AllArgsConstructor; +import me.chanjar.weixin.common.error.WxErrorException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationServiceException; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; +import org.springframework.security.web.authentication.AuthenticationFailureHandler; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.stereotype.Component; + +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +/** + * 账号密码登录 + */ +@Component +public class WebLoginAuthenticationFilter extends AbstractAuthenticationProcessingFilter { + + private final YamiUserDetailsService yamiUserDetailsService; + + private final WxMaService wxMaService; + + @Autowired + public WebLoginAuthenticationFilter(YamiUserDetailsService yamiUserDetailsService, WxMaService wxMaService) { + super("/webLogin"); + this.yamiUserDetailsService = yamiUserDetailsService; + this.wxMaService = wxMaService; + } + + @Override + public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { + if (!ServletUtil.METHOD_POST.equals(request.getMethod())) { + throw new AuthenticationServiceException( + "Authentication method not supported: " + request.getMethod()); + } + String requestBody = getStringFromStream(request); + + if (StrUtil.isBlank(requestBody)) { + throw new AuthenticationServiceException("无法获取输入信息"); + } + WebAuthenticationToken authentication = Json.parseObject(requestBody, WebAuthenticationToken.class); + String userMail = String.valueOf(authentication.getPrincipal()); + String loginPassword = String.valueOf(authentication.getCredentials()); + + YamiUser loadedUser = null; + +// WxMaJscode2SessionResult session = null; + + AppConnect appConnect = new AppConnect(); + appConnect.setAppId(App.H5.value()); + loadedUser = yamiUserDetailsService.loadUserByUserMail(userMail,loginPassword); +// try { +// +//// session = wxMaService.getUserService().getSessionInfo(code); +// +// loadedUser = yamiUserDetailsService.loadUserByAppIdAndBizUserId(App.MINI,session.getOpenid()); +// } catch (WxErrorException e) { +// throw new WxErrorExceptionBase(e.getMessage()); +// } catch (UsernameNotFoundExceptionBase var6) { +// if (session == null) { +// throw new WxErrorExceptionBase("无法获取用户登陆信息"); +// } +// appConnect.setBizUserId(session.getOpenid()); +// appConnect.setBizUnionid(session.getUnionid()); +// yamiUserDetailsService.insertUserIfNecessary(appConnect); +// } + +// if (loadedUser == null) { +// loadedUser = yamiUserDetailsService.loadUserByAppIdAndBizUserId(App.MINI, appConnect.getBizUserId()); +// } +// MiniAppAuthenticationToken result = new MiniAppAuthenticationToken(loadedUser, authentication.getCredentials()); + WebAuthenticationToken result = new WebAuthenticationToken(loadedUser, authentication.getCredentials()); + result.setDetails(authentication.getDetails()); + return result; + } + + + private String getStringFromStream(HttpServletRequest req) { + ServletInputStream is; + try { + is = req.getInputStream(); + int nRead = 1; + int nTotalRead = 0; + byte[] bytes = new byte[10240]; + while (nRead > 0) { + nRead = is.read(bytes, nTotalRead, bytes.length - nTotalRead); + if (nRead > 0) { + nTotalRead = nTotalRead + nRead; + } + } + return new String(bytes, 0, nTotalRead, StandardCharsets.UTF_8); + } catch (IOException e) { + e.printStackTrace(); + return ""; + } + } + + @Override + @Autowired + public void setAuthenticationManager(AuthenticationManager authenticationManager) { + super.setAuthenticationManager(authenticationManager); + } + + @Override + @Autowired + public void setAuthenticationSuccessHandler(AuthenticationSuccessHandler successHandler) { + super.setAuthenticationSuccessHandler(successHandler); + } + + @Override + @Autowired + public void setAuthenticationFailureHandler(AuthenticationFailureHandler failureHandler) { + super.setAuthenticationFailureHandler(failureHandler); + } +} diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/security/YamiAuthenticationProcessingFilter.java b/yami-shop-api/src/main/java/com/yami/shop/api/security/YamiAuthenticationProcessingFilter.java new file mode 100644 index 0000000..85763c2 --- /dev/null +++ b/yami-shop-api/src/main/java/com/yami/shop/api/security/YamiAuthenticationProcessingFilter.java @@ -0,0 +1,154 @@ +package com.yami.shop.api.security; + +import cn.hutool.extra.servlet.ServletUtil; +import com.yami.shop.common.exception.YamiShopBindException; +import com.yami.shop.common.util.Json; +import com.yami.shop.common.xss.XssUtil; +import com.yami.shop.security.exception.BadCredentialsException; +import com.yami.shop.security.exception.UsernameNotFoundException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; +import org.springframework.security.web.authentication.AuthenticationFailureHandler; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.springframework.web.HttpRequestMethodNotSupportedException; + +import javax.servlet.ServletException; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +/** + * + * @author SJL + */ +public class YamiAuthenticationProcessingFilter extends AbstractAuthenticationProcessingFilter { + + private UserDetailsService userDetailsService; + + private PasswordEncoder passwordEncoder; + /** + * 请求字符串的最大长度 1m + */ + public static final int MAX_STRING_SIZE = 1024 * 1024; + + protected YamiAuthenticationProcessingFilter(String defaultFilterProcessesUrl) { + super(defaultFilterProcessesUrl); + } + + @Autowired + public void setPasswordEncoder(PasswordEncoder passwordEncoder) { + this.passwordEncoder = passwordEncoder; + } + + @Autowired + public void setUserDetailsService(UserDetailsService userDetailsService) { + this.userDetailsService = userDetailsService; + } + + @Override + @Autowired + public void setAuthenticationManager(AuthenticationManager authenticationManager) { + super.setAuthenticationManager(authenticationManager); + } + + @Override + @Autowired + public void setAuthenticationSuccessHandler(AuthenticationSuccessHandler successHandler) { + super.setAuthenticationSuccessHandler(successHandler); + } + + @Override + @Autowired + public void setAuthenticationFailureHandler(AuthenticationFailureHandler failureHandler) { + super.setAuthenticationFailureHandler(failureHandler); + } + + @Override + public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, ServletException{ + if (!ServletUtil.METHOD_POST.equals(request.getMethod())) { + throw new HttpRequestMethodNotSupportedException(request.getMethod(), new String[] { "POST" }); + } + + AuthenticationToken authenticationToken = Json.parseObject(getStringFromStream(request), AuthenticationToken.class); + UserDetails userDetails = getUserDetails(authenticationToken); + return handleAuthenticationToken(authenticationToken,userDetails); + } + + /** + * 获取用户信息 + * @param authenticationToken + * @return + */ + protected UserDetails getUserDetails(AuthenticationToken authenticationToken) { + UserDetails user; + try { + user = userDetailsService.loadUserByUsername(authenticationToken.getPrincipal()); + } catch (UsernameNotFoundException var6) { + // 账号或密码不正确 + throw new UsernameNotFoundException("账号或密码不正确"); + } + if (!user.isEnabled()) { + // 账号已被锁定,请联系管理员 + throw new UsernameNotFoundException("账号已被锁定,请联系管理员"); + } + + String encodedPassword = user.getPassword(); + String rawPassword = authenticationToken.getCredentials().toString(); + + // 密码不正确 + if (!passwordEncoder.matches(rawPassword,encodedPassword)){ + // 账号或密码不正确 + throw new BadCredentialsException("账号或密码不正确"); + } + return user; + } + + + /** + * 保存用户信息 + */ + protected AuthenticationToken handleAuthenticationToken(AuthenticationToken authentication, UserDetails userDetails) { + // 保存用户信息 + authentication.setPrincipal(userDetails.getUsername()); + authentication.setDetails(userDetails); + authentication.setAuthenticated(true); + return authentication; + } + + + public String getStringFromStream(HttpServletRequest req) { + if (req.getContentLength() > MAX_STRING_SIZE) { + // 请求数据过长 + throw new YamiShopBindException("yami.request.data.too.long"); + } + ServletInputStream is; + try { + is = req.getInputStream(); + int nRead = 1; + int nTotalRead = 0; + byte[] bytes = new byte[1024]; + while (nRead > 0) { + nRead = is.read(bytes, nTotalRead, bytes.length - nTotalRead); + if (nRead > 0) { + nTotalRead = nTotalRead + nRead; + } + } + if (nTotalRead > MAX_STRING_SIZE) { + // 请求数据过长 + throw new YamiShopBindException("yami.request.data.too.long"); + } + return XssUtil.clean(new String(bytes, 0, nTotalRead, StandardCharsets.UTF_8)); + } catch (IOException e) { + e.printStackTrace(); + return ""; + } + } +} diff --git a/yami-shop-api/src/main/java/com/yami/shop/api/security/YamiUserServiceImpl.java b/yami-shop-api/src/main/java/com/yami/shop/api/security/YamiUserServiceImpl.java index a690039..72a47a6 100644 --- a/yami-shop-api/src/main/java/com/yami/shop/api/security/YamiUserServiceImpl.java +++ b/yami-shop-api/src/main/java/com/yami/shop/api/security/YamiUserServiceImpl.java @@ -15,6 +15,7 @@ import cn.hutool.core.util.StrUtil; import cn.hutool.extra.emoji.EmojiUtil; import com.yami.shop.bean.model.User; import com.yami.shop.common.annotation.RedisLock; +import com.yami.shop.common.exception.YamiShopBindException; import com.yami.shop.common.util.CacheManagerUtil; import com.yami.shop.dao.UserMapper; import com.yami.shop.security.dao.AppConnectMapper; @@ -28,6 +29,8 @@ import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Caching; +import org.springframework.http.ResponseEntity; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -47,9 +50,7 @@ public class YamiUserServiceImpl implements YamiUserDetailsService { private final AppConnectMapper appConnectMapper; - private final CacheManagerUtil cacheManagerUtil; - - + private final PasswordEncoder passwordEncoder; @Override @SneakyThrows public YamiUser loadUserByUsername(String username) { @@ -127,4 +128,22 @@ public class YamiUserServiceImpl implements YamiUserDetailsService { appConnectMapper.insert(appConnect); } + + @Override + public YamiUser loadUserByUserMail(String userMail, String loginPassword) { + User user = userMapper.getUserByUserMail(userMail); + if (user == null) { + throw new YamiShopBindException("用户不存在"); + } + String paramPassword = passwordEncoder.encode(loginPassword); + if (!passwordEncoder.matches(loginPassword, user.getLoginPassword())) { + // 原密码不正确 + throw new YamiShopBindException("密码不正确"); + } + String name = StrUtil.isBlank(user.getRealName()) ? user.getNickName() : user.getRealName(); + YamiUser yamiUser = new YamiUser(user.getUserId(), loginPassword, user.getStatus() == 1); + yamiUser.setName(name); + yamiUser.setPic(user.getPic()); + return yamiUser; + } } diff --git a/yami-shop-bean/src/main/java/com/yami/shop/bean/param/UserRegisterParam.java b/yami-shop-bean/src/main/java/com/yami/shop/bean/param/UserRegisterParam.java new file mode 100644 index 0000000..faa9210 --- /dev/null +++ b/yami-shop-bean/src/main/java/com/yami/shop/bean/param/UserRegisterParam.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved. + * + * https://www.gz-yami.com/ + * + * 未经允许,不可做商业用途! + * + * 版权所有,侵权必究! + */ + +package com.yami.shop.bean.param; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +@ApiModel(value= "设置用户信息") +public class UserRegisterParam { + + @ApiModelProperty(value = "密码") + private String password; + + @ApiModelProperty(value = "邮箱") + private String userMail; + + @ApiModelProperty(value = "昵称") + private String nickName; + + @ApiModelProperty(value = "用户名") + private String userName; + + @ApiModelProperty(value = "应用类型 1小程序 2微信公众号 3 PC 4 h5") + private Integer appType; +} diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/enums/App.java b/yami-shop-security/src/main/java/com/yami/shop/security/enums/App.java index 105a868..124e6b1 100644 --- a/yami-shop-security/src/main/java/com/yami/shop/security/enums/App.java +++ b/yami-shop-security/src/main/java/com/yami/shop/security/enums/App.java @@ -20,19 +20,24 @@ public enum App { /** * 微信公众号 */ - MP(2) + MP(2), + + /** + * H5 + */ + H5(3) ; - + private Integer num; - + public Integer value() { return num; } - + App(Integer num){ this.num = num; } - + public static App instance(Integer value) { App[] enums = values(); for (App statusEnum : enums) { diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/service/YamiUser.java b/yami-shop-security/src/main/java/com/yami/shop/security/service/YamiUser.java index 7c8ed48..b2f6fda 100644 --- a/yami-shop-security/src/main/java/com/yami/shop/security/service/YamiUser.java +++ b/yami-shop-security/src/main/java/com/yami/shop/security/service/YamiUser.java @@ -28,8 +28,10 @@ public class YamiUser extends User { /** * 用户ID */ + @Setter private String userId; + @Setter private String bizUserId; @Setter @@ -41,6 +43,15 @@ public class YamiUser extends User { @Setter private boolean debugger; + @Setter + private String password; + + public YamiUser(String userId, String password, boolean enabled) { + super(userId, password, enabled,true, true, true , Collections.emptyList()); + this.userId = userId; + this.password = password; + } + public YamiUser(String userId, String bizUserId, Integer appId, boolean enabled) { super(appId + StrUtil.COLON + bizUserId, "", enabled,true, true, true , Collections.emptyList()); this.userId = userId; diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/service/YamiUserDetailsService.java b/yami-shop-security/src/main/java/com/yami/shop/security/service/YamiUserDetailsService.java index 6ce71e4..c45ec83 100644 --- a/yami-shop-security/src/main/java/com/yami/shop/security/service/YamiUserDetailsService.java +++ b/yami-shop-security/src/main/java/com/yami/shop/security/service/YamiUserDetailsService.java @@ -37,4 +37,12 @@ public interface YamiUserDetailsService extends UserDetailsService { * @param appConnect */ void insertUserIfNecessary(AppConnect appConnect); + + /** + * 账号、密码登录 + * @param userMail + * @param loginPassword + * @return + */ + YamiUser loadUserByUserMail(String userMail, String loginPassword); } diff --git a/yami-shop-security/src/main/java/com/yami/shop/security/util/YamiTokenServices.java b/yami-shop-security/src/main/java/com/yami/shop/security/util/YamiTokenServices.java index 0be5b59..f4e17b9 100644 --- a/yami-shop-security/src/main/java/com/yami/shop/security/util/YamiTokenServices.java +++ b/yami-shop-security/src/main/java/com/yami/shop/security/util/YamiTokenServices.java @@ -84,7 +84,7 @@ public class YamiTokenServices implements AuthorizationServerTokenServices, Reso @Override public OAuth2AccessToken createAccessToken(OAuth2Authentication authentication) { - OAuth2AccessToken existingAccessToken = tokenStore.getAccessToken(authentication); +// OAuth2AccessToken existingAccessToken = tokenStore.getAccessToken(authentication); OAuth2RefreshToken refreshToken = null; // 如果有token,直接删除,更新token,避免出现缓存问题 // if (existingAccessToken != null) { diff --git a/yami-shop-service/src/main/java/com/yami/shop/dao/UserMapper.java b/yami-shop-service/src/main/java/com/yami/shop/dao/UserMapper.java index 174a034..90ff2aa 100644 --- a/yami-shop-service/src/main/java/com/yami/shop/dao/UserMapper.java +++ b/yami-shop-service/src/main/java/com/yami/shop/dao/UserMapper.java @@ -18,4 +18,6 @@ import org.apache.ibatis.annotations.Param; public interface UserMapper extends BaseMapper { User getUserByBizUserId(@Param("appId")Integer appId, @Param("bizUserId")String bizUserId); + + User getUserByUserMail(@Param("userMail") String userMail); } diff --git a/yami-shop-service/src/main/java/com/yami/shop/service/UserService.java b/yami-shop-service/src/main/java/com/yami/shop/service/UserService.java index fd3f32a..61e3d09 100644 --- a/yami-shop-service/src/main/java/com/yami/shop/service/UserService.java +++ b/yami-shop-service/src/main/java/com/yami/shop/service/UserService.java @@ -12,6 +12,7 @@ package com.yami.shop.service; import com.baomidou.mybatisplus.extension.service.IService; import com.yami.shop.bean.model.User; +import com.yami.shop.bean.param.UserRegisterParam; import com.yami.shop.bean.vo.UserVO; /** @@ -21,4 +22,6 @@ import com.yami.shop.bean.vo.UserVO; public interface UserService extends IService { User getUserByUserId(String userId); + + Boolean insertUser(UserRegisterParam userRegisterParam); } diff --git a/yami-shop-service/src/main/java/com/yami/shop/service/impl/UserServiceImpl.java b/yami-shop-service/src/main/java/com/yami/shop/service/impl/UserServiceImpl.java index 4078f08..f68acc0 100644 --- a/yami-shop-service/src/main/java/com/yami/shop/service/impl/UserServiceImpl.java +++ b/yami-shop-service/src/main/java/com/yami/shop/service/impl/UserServiceImpl.java @@ -10,9 +10,14 @@ package com.yami.shop.service.impl; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.extra.emoji.EmojiUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.yami.shop.bean.model.User; +import com.yami.shop.bean.param.UserRegisterParam; import com.yami.shop.bean.vo.UserVO; +import com.yami.shop.common.exception.YamiShopBindException; import com.yami.shop.dao.UserMapper; import com.yami.shop.service.UserService; import org.springframework.beans.factory.annotation.Autowired; @@ -34,8 +39,26 @@ public class UserServiceImpl extends ServiceImpl implements Us @Override - @Cacheable(cacheNames="user",key="#userId") + @Cacheable(cacheNames = "user", key = "#userId") public User getUserByUserId(String userId) { return userMapper.selectById(userId); } + + @Override + public Boolean insertUser(UserRegisterParam uParam) { + User mail = userMapper.getUserByUserMail(uParam.getUserMail()); + if (mail != null) { + throw new YamiShopBindException("账号已存在"); + } + Date now = new Date(); + User user = new User(); + user.setUserId(IdUtil.simpleUUID()); + user.setModifyTime(now); + user.setUserRegtime(now); + user.setStatus(1); + user.setNickName(uParam.getUserMail()); + user.setUserMail(uParam.getUserMail()); + user.setLoginPassword(uParam.getPassword()); + return userMapper.insert(user) == 1; + } } diff --git a/yami-shop-service/src/main/resources/mapper/UserMapper.xml b/yami-shop-service/src/main/resources/mapper/UserMapper.xml index bf46fc6..0e5ac47 100644 --- a/yami-shop-service/src/main/resources/mapper/UserMapper.xml +++ b/yami-shop-service/src/main/resources/mapper/UserMapper.xml @@ -28,7 +28,11 @@ select * from tz_user u where u.user_id = (select user_id from tz_app_connect ac where ac.app_id = #{appId} and ac.biz_user_id = #{bizUserId}) - +