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("用户不存在");
|
}
|
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);
|
}
|
}
|
}
|
}
|