| package com.mzl.flower.web.login; | 
|   | 
| import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; | 
| import cn.hutool.core.util.StrUtil; | 
| import com.mzl.flower.base.BaseController; | 
| import com.mzl.flower.base.R; | 
| import com.mzl.flower.base.ReturnDataDTO; | 
| import com.mzl.flower.base.cache.StringCacheClient; | 
| import com.mzl.flower.config.exception.BaseException; | 
| import com.mzl.flower.config.exception.ValidationException; | 
| import com.mzl.flower.config.security.token.PhoneAuthenticationToken; | 
| import com.mzl.flower.config.security.token.UserIdAuthenticationToken; | 
| import com.mzl.flower.config.security.token.WebAuthenticationToken; | 
| import com.mzl.flower.constant.Constants; | 
| import com.mzl.flower.dto.request.CreateWechatUserDTO; | 
| import com.mzl.flower.dto.request.UserLoginDTO; | 
| import com.mzl.flower.dto.response.customer.CustomerDTO; | 
| import com.mzl.flower.entity.system.User; | 
| import com.mzl.flower.mapper.customer.CustomerMapper; | 
| import com.mzl.flower.service.customer.CustomerService; | 
| import com.mzl.flower.service.login.LoginService; | 
| import com.mzl.flower.service.system.UserService; | 
| import com.mzl.flower.service.system.WeChatService; | 
| import io.swagger.annotations.Api; | 
| import io.swagger.annotations.ApiOperation; | 
| import lombok.extern.slf4j.Slf4j; | 
| import org.apache.commons.lang3.StringUtils; | 
| import org.springframework.beans.factory.annotation.Autowired; | 
| import org.springframework.http.ResponseEntity; | 
| import org.springframework.security.authentication.AuthenticationDetailsSource; | 
| import org.springframework.security.authentication.AuthenticationManager; | 
| import org.springframework.security.authentication.BadCredentialsException; | 
| import org.springframework.security.core.Authentication; | 
| import org.springframework.security.core.userdetails.UsernameNotFoundException; | 
| import org.springframework.security.oauth2.common.OAuth2AccessToken; | 
| import org.springframework.security.oauth2.common.OAuth2RefreshToken; | 
| import org.springframework.security.oauth2.provider.token.TokenStore; | 
| import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; | 
| import org.springframework.util.ObjectUtils; | 
| import org.springframework.web.bind.annotation.*; | 
|   | 
| import javax.servlet.http.HttpServletRequest; | 
| import javax.validation.constraints.NotBlank; | 
|   | 
| @Slf4j | 
| @RestController | 
| @RequestMapping("/api") | 
| @Api(value = "会员登录", tags = "会员登录") | 
| public class CustomerLoginController extends BaseController { | 
|   | 
|     private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource(); | 
|   | 
|     @Autowired | 
|     private AuthenticationManager authenticationManager; | 
|   | 
|     @Autowired | 
|     private LoginService loginService; | 
|   | 
|     @Autowired | 
|     private StringCacheClient stringCacheClient; | 
|   | 
|     @Autowired | 
|     private WeChatService weChatService; | 
|   | 
|     @Autowired | 
|     private UserService userService; | 
|   | 
|     @Autowired | 
|     private CustomerMapper customerMapper; | 
|   | 
|   | 
|     @Autowired | 
|     private TokenStore tokenStore; | 
|     public static final String SMS_CODE_KEY = "SMS-CODE-KEY"; | 
|     public static final String TOKEN_KEY = "TOKEN-KEY"; | 
|   | 
|     public static final String SEPARATOR = ":"; | 
|   | 
|     @PostMapping("/login/wechat") | 
|     @ApiOperation(value = "微信小程序登录", notes = "微信小程序登录") | 
|     public ResponseEntity<ReturnDataDTO<OAuth2AccessToken>> loginWeChat( | 
|             HttpServletRequest request,@RequestBody CreateWechatUserDTO dto) throws Exception { | 
|         WxMaJscode2SessionResult session = weChatService.getWxMaSessionInfo(dto.getCode()); | 
|         String openId = session.getOpenid(); | 
|         String sessionKey = session.getSessionKey(); | 
|         String unionId = session.getUnionid(); | 
|         User user = userService.findUserByOpenId(openId, sessionKey, unionId | 
|                 , dto.getImgUrl(), dto.getNickname(),Constants.USER_TYPE.customer.name()); | 
|         String tokenCache = stringCacheClient.get(TOKEN_KEY + SEPARATOR + user.getId()); | 
|         if (StringUtils.isNotBlank(tokenCache))  { | 
|             //强制删除token,下线 | 
|             removeToken(tokenCache,user.getId()); | 
|         } | 
|         try { | 
|             UserIdAuthenticationToken authRequest = new UserIdAuthenticationToken(user.getId(), null); | 
|             authRequest.setDetails(authenticationDetailsSource.buildDetails(request)); | 
|             Authentication authentication = authenticationManager.authenticate(authRequest); | 
|             OAuth2AccessToken token = loginService.getAccessToken(authentication, Constants.USER_TYPE.customer.name()); | 
|             stringCacheClient.set(TOKEN_KEY + SEPARATOR + user.getId(),token.getValue()); | 
|             return returnData(R.SUCCESS.getCode(), token); | 
|         } catch (BadCredentialsException e) { | 
|             throw new ValidationException("用户名或密码错误"); | 
|         } catch (UsernameNotFoundException e) { | 
|             throw new ValidationException("用户不存在"); | 
|         } catch (Exception e) { | 
|             log.error(e.getMessage(), e); | 
|             throw new BaseException(R.RUNTIME_EXCEPTION.getCode(), "登录错误"); | 
|         } | 
|     } | 
|   | 
|     @GetMapping("/wx/jscode2session") | 
|     @ApiOperation(value = "微信小程序授权") | 
|     public ResponseEntity<ReturnDataDTO> jscode2session(@NotBlank(message = "授权码不能为空") String jsCode,String userType) throws Exception{ | 
|         return returnData(R.SUCCESS.getCode(), weChatService.getWechatOpenId(jsCode,userType)); | 
|     } | 
|   | 
|   | 
|     @PostMapping("/login/customer") | 
|     @ApiOperation(value = "商户账号密码登录", notes = "商户账号密码登录") | 
|     public ResponseEntity<ReturnDataDTO<OAuth2AccessToken>> loginPerson(HttpServletRequest request | 
|             , @RequestBody UserLoginDTO loginDTO) { | 
|         String username = loginDTO.getUsername(); | 
|         String password = loginDTO.getPassword(); | 
|         if (StringUtils.isBlank(username)) { | 
|             throw new ValidationException("用户名不能为空"); | 
|         } | 
|         if (StringUtils.isBlank(password)) { | 
|             throw new ValidationException("密码不能为空"); | 
|         } | 
|   | 
|         User user = userService.findByTel(username, Constants.USER_TYPE.customer.name()); | 
|         if(user == null){ | 
|             throw new ValidationException("用户不存在"); | 
|         } | 
|         CustomerDTO currentCustomer = customerMapper.getCurrentCustomer(user.getId()); | 
|         if (ObjectUtils.isEmpty(currentCustomer)) { | 
|             throw new ValidationException("用户不存在"); | 
|         } | 
|         if (currentCustomer.getIsEnabled() == false) { | 
|             throw new ValidationException("用户已禁用,请联系管理员"); | 
|         } | 
|         String tokenCache = stringCacheClient.get(TOKEN_KEY + SEPARATOR + user.getId()); | 
|         if (StringUtils.isNotBlank(tokenCache))  { | 
|             //强制删除token,下线 | 
|             removeToken(tokenCache,user.getId()); | 
|         } | 
|   | 
|         try { | 
|             WebAuthenticationToken authRequest = new WebAuthenticationToken(username, password); | 
|             authRequest.setDetails(authenticationDetailsSource.buildDetails(request)); | 
|             Authentication authentication = authenticationManager.authenticate(authRequest); | 
|             OAuth2AccessToken token = loginService.getAccessToken(authentication,Constants.USER_TYPE.customer.name()); | 
|             stringCacheClient.set(TOKEN_KEY + SEPARATOR + user.getId(),token.getValue()); | 
|             return returnData(R.SUCCESS.getCode(),token); | 
|         }catch (BadCredentialsException e){ | 
|             throw new ValidationException("用户名或密码错误"); | 
|         }catch (UsernameNotFoundException e){ | 
|             throw new ValidationException("用户不存在"); | 
|         }catch (Exception e) { | 
|             log.error(e.getMessage(), e); | 
|             throw new BaseException(R.RUNTIME_EXCEPTION.getCode(),"登录错误"); | 
|         } | 
|     } | 
|   | 
|   | 
|     @PostMapping("/login/customer/phone") | 
|     @ApiOperation(value = "手机验证码登录系统", notes = "手机验证码登录系统") | 
|     public ResponseEntity<ReturnDataDTO<OAuth2AccessToken>>  loginPhone(HttpServletRequest request, | 
|                                                                         @RequestBody UserLoginDTO loginDTO) { | 
|         String tel = loginDTO.getUsername(); | 
|         String smsCode = loginDTO.getSmsCode(); | 
|         if (StringUtils.isBlank(tel)) { | 
|             throw new ValidationException("手机号码不能为空"); | 
|         } | 
|         if (StringUtils.isBlank(smsCode)) { | 
|             throw new ValidationException("手机验证码不能为空"); | 
|         } | 
|         //从缓存中获取验证码 | 
|         String smsCacheCode = stringCacheClient.get(SMS_CODE_KEY + SEPARATOR + Constants.USER_TYPE.customer.name() + SEPARATOR + tel); | 
|         if (!StringUtils.equals(smsCode, smsCacheCode)) { | 
|             throw new ValidationException("手机验证码不正确"); | 
|         } | 
|   | 
|         User user = userService.findByTel(tel, Constants.USER_TYPE.customer.name()); | 
|         if(user == null){ | 
|             throw new ValidationException("用户不存在"); | 
|         } | 
|         CustomerDTO currentCustomer = customerMapper.getCurrentCustomer(user.getId()); | 
|         if (ObjectUtils.isEmpty(currentCustomer)) { | 
|             throw new ValidationException("用户不存在"); | 
|         } | 
|         if (currentCustomer.getIsEnabled() == false) { | 
|             throw new ValidationException("用户已禁用,请联系管理员"); | 
|         } | 
|         String tokenCache = stringCacheClient.get(TOKEN_KEY + SEPARATOR + user.getId()); | 
|         if (StringUtils.isNotBlank(tokenCache))  { | 
|             //强制删除token,下线 | 
|             removeToken(tokenCache,user.getId()); | 
|         } | 
|   | 
|         try { | 
|             PhoneAuthenticationToken authRequest = new PhoneAuthenticationToken(tel, smsCode, Constants.USER_TYPE.customer.name()); | 
|             authRequest.setDetails(authenticationDetailsSource.buildDetails(request)); | 
|             Authentication authentication = authenticationManager.authenticate(authRequest); | 
|             OAuth2AccessToken token = loginService.getAccessToken(authentication, Constants.USER_TYPE.customer.name()); | 
|             //删除缓存中的验证码 | 
|             stringCacheClient.delete(SMS_CODE_KEY + SEPARATOR + Constants.USER_TYPE.customer.name() + SEPARATOR + tel); | 
|             stringCacheClient.set(TOKEN_KEY + SEPARATOR + user.getId(),token.getValue()); | 
|             return returnData(R.SUCCESS.getCode(),token); | 
|         }catch (UsernameNotFoundException e){ | 
|             throw new ValidationException("手机号未注册"); | 
|         }catch (Exception e) { | 
|             log.error(e.getMessage(), e); | 
|             throw new BaseException(R.RUNTIME_EXCEPTION.getCode(),"登录错误"); | 
|         } | 
|     } | 
|   | 
|     public void removeToken(String token,String userId) { | 
|         if (StringUtils.isNotBlank(token) && StringUtils.isNotBlank(userId))  { | 
|             stringCacheClient.delete(TOKEN_KEY + SEPARATOR + userId); | 
|             String tokenValue = token.replace(OAuth2AccessToken.BEARER_TYPE, StrUtil.EMPTY).trim(); | 
|             OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue); | 
|             if (accessToken != null && StringUtils.isNotBlank(accessToken.getValue())) { | 
|                 tokenStore.removeAccessToken(accessToken); | 
|                 OAuth2RefreshToken refreshToken = accessToken.getRefreshToken(); | 
|                 tokenStore.removeRefreshToken(refreshToken); | 
|             } | 
|         } | 
|     } | 
| } |