增加手机验证码登录
This commit is contained in:
parent
4c79271601
commit
594a732d14
@ -87,6 +87,7 @@ public class SystemUserRouteController extends DefaultBaseController {
|
|||||||
public ModelAndView login(HttpServletRequest request) {
|
public ModelAndView login(HttpServletRequest request) {
|
||||||
ModelAndView mv = new ModelAndView();
|
ModelAndView mv = new ModelAndView();
|
||||||
Map<String, String> pageParams = oAuthService.getPageParams(request);
|
Map<String, String> pageParams = oAuthService.getPageParams(request);
|
||||||
|
pageParams.put("loginPhoneAction", "oauth/phone");
|
||||||
mv.addObject(IUserCenterConst.PAGE_PARAMS, pageParams);
|
mv.addObject(IUserCenterConst.PAGE_PARAMS, pageParams);
|
||||||
mv.addObject(IUserCenterConst.CUSTOM_LOGIN_FORM, loginFormService.getActive());
|
mv.addObject(IUserCenterConst.CUSTOM_LOGIN_FORM, loginFormService.getActive());
|
||||||
mv.addObject("HomeServerUrl", ProjectConfigUtil.getText("HomeServerUrl"));
|
mv.addObject("HomeServerUrl", ProjectConfigUtil.getText("HomeServerUrl"));
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
package cn.com.tenlion.operator.login.phone;
|
||||||
|
|
||||||
|
import cn.com.tenlion.operator.login.phone.auth.LoginPhoneAuthFilter;
|
||||||
|
import cn.com.tenlion.operator.login.phone.auth.LoginPhoneAuthProvider;
|
||||||
|
import ink.wgink.interfaces.config.ICustomUserSecurityConfig;
|
||||||
|
import ink.wgink.interfaces.expand.login.ILoginHandlerService;
|
||||||
|
import ink.wgink.login.base.handler.LoginFailureHandler;
|
||||||
|
import ink.wgink.login.base.service.user.UserLoginService;
|
||||||
|
import ink.wgink.module.sms.service.sms.ISmsService;
|
||||||
|
import ink.wgink.properties.BaseProperties;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
import org.springframework.security.web.DefaultSecurityFilterChain;
|
||||||
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class LoginPhoneConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> implements ICustomUserSecurityConfig {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private BaseProperties baseProperties;
|
||||||
|
@Autowired
|
||||||
|
private UserDetailsService userDetailsService;
|
||||||
|
@Autowired
|
||||||
|
private UserLoginService userLoginService;
|
||||||
|
@Autowired(required = false)
|
||||||
|
private ILoginHandlerService loginHandler;
|
||||||
|
@Autowired
|
||||||
|
private HttpSession httpSession;
|
||||||
|
@Autowired
|
||||||
|
private ISmsService smsService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure(HttpSecurity http) throws Exception {
|
||||||
|
super.configure(http);
|
||||||
|
LoginPhoneAuthFilter loginPhoneAuthFilter = new LoginPhoneAuthFilter(smsService);
|
||||||
|
loginPhoneAuthFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));
|
||||||
|
loginPhoneAuthFilter.setAuthenticationFailureHandler(new LoginFailureHandler(baseProperties.getLoginFailure()));
|
||||||
|
|
||||||
|
LoginPhoneAuthProvider loginPhoneAuthProvider = new LoginPhoneAuthProvider(userDetailsService,
|
||||||
|
userLoginService,
|
||||||
|
loginHandler,
|
||||||
|
httpSession
|
||||||
|
);
|
||||||
|
http.authenticationProvider(loginPhoneAuthProvider).addFilterBefore(loginPhoneAuthFilter, UsernamePasswordAuthenticationFilter.class);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package cn.com.tenlion.operator.login.phone.auth;
|
||||||
|
|
||||||
|
import ink.wgink.login.base.exceptions.UserAuthenticationException;
|
||||||
|
import ink.wgink.module.sms.service.sms.ISmsService;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
|
||||||
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class LoginPhoneAuthFilter extends AbstractAuthenticationProcessingFilter {
|
||||||
|
|
||||||
|
private ISmsService smsService;
|
||||||
|
|
||||||
|
public LoginPhoneAuthFilter(ISmsService smsService) {
|
||||||
|
super(new AntPathRequestMatcher("/oauth/phone", "POST"));
|
||||||
|
this.smsService = smsService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
|
||||||
|
String phone = request.getParameter("username").trim();
|
||||||
|
String code = request.getParameter("code").trim();
|
||||||
|
if (StringUtils.isBlank(phone)) {
|
||||||
|
throw new UserAuthenticationException("手机号不能为空");
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(code)) {
|
||||||
|
throw new UserAuthenticationException("验证码不能为空");
|
||||||
|
}
|
||||||
|
// String verifyCode = smsService.getVerifyCode(phone);
|
||||||
|
// if (StringUtils.isBlank(verifyCode)) {
|
||||||
|
// throw new UserAuthenticationException("验证码错误");
|
||||||
|
// }
|
||||||
|
// if (!StringUtils.equals(code, verifyCode)) {
|
||||||
|
// throw new UserAuthenticationException("验证码不匹配");
|
||||||
|
// }
|
||||||
|
LoginPhoneAuthToken loginPhoneAuthToken = new LoginPhoneAuthToken(phone, null);
|
||||||
|
loginPhoneAuthToken.setDetails(authenticationDetailsSource.buildDetails(request));
|
||||||
|
return this.getAuthenticationManager().authenticate(loginPhoneAuthToken);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
package cn.com.tenlion.operator.login.phone.auth;
|
||||||
|
|
||||||
|
import ink.wgink.interfaces.expand.login.ILoginHandlerService;
|
||||||
|
import ink.wgink.login.base.consts.IUserCenterConst;
|
||||||
|
import ink.wgink.login.base.enums.LoginTypeEnum;
|
||||||
|
import ink.wgink.login.base.exceptions.UserAuthenticationException;
|
||||||
|
import ink.wgink.login.base.service.user.UserLoginService;
|
||||||
|
import ink.wgink.pojo.bos.LoginUser;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.security.authentication.AuthenticationProvider;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
public class LoginPhoneAuthProvider implements AuthenticationProvider {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(LoginPhoneAuthProvider.class);
|
||||||
|
private UserDetailsService userDetailsService;
|
||||||
|
private UserLoginService userLoginService;
|
||||||
|
private ILoginHandlerService loginHandler;
|
||||||
|
private HttpSession httpSession;
|
||||||
|
|
||||||
|
public LoginPhoneAuthProvider(UserDetailsService userDetailsService, UserLoginService userLoginService, ILoginHandlerService loginHandler, HttpSession httpSession) {
|
||||||
|
this.userDetailsService = userDetailsService;
|
||||||
|
this.userLoginService = userLoginService;
|
||||||
|
this.loginHandler = loginHandler;
|
||||||
|
this.httpSession = httpSession;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||||
|
LoginPhoneAuthToken loginPhoneAuthToken = (LoginPhoneAuthToken) authentication;
|
||||||
|
String username = (String) loginPhoneAuthToken.getPrincipal();
|
||||||
|
httpSession.setAttribute(IUserCenterConst.LOGIN_USERNAME, username);
|
||||||
|
LoginUser loginUser = (LoginUser) userDetailsService.loadUserByUsername(username);
|
||||||
|
userLoginService.setLoginUserInfo(loginUser);
|
||||||
|
if (loginUser.getAuthorities().isEmpty()) {
|
||||||
|
throw new UserAuthenticationException(loginUser.getUsername() + "用户无任何角色");
|
||||||
|
}
|
||||||
|
// 登录逻辑处理
|
||||||
|
loginHandler(loginUser);
|
||||||
|
// 清空session中的错误信息
|
||||||
|
httpSession.removeAttribute(IUserCenterConst.ERROR_MESSAGE);
|
||||||
|
httpSession.removeAttribute(IUserCenterConst.LOGIN_USERNAME);
|
||||||
|
// 更新登录信息
|
||||||
|
userLoginService.updateUserLoginInfo(loginUser.getUserId(), loginUser.getUserName(), LoginTypeEnum.USERNAME_AND_PASSWORD.getValue());
|
||||||
|
LoginPhoneAuthToken loginPhoneAuthTokenResult = new LoginPhoneAuthToken(loginUser, null, loginUser.getAuthorities());
|
||||||
|
loginPhoneAuthTokenResult.setDetails(loginPhoneAuthToken.getDetails());
|
||||||
|
return loginPhoneAuthTokenResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supports(Class<?> aClass) {
|
||||||
|
return LoginPhoneAuthToken.class.isAssignableFrom(aClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录处理
|
||||||
|
*
|
||||||
|
* @param loginUser
|
||||||
|
*/
|
||||||
|
private void loginHandler(LoginUser loginUser) {
|
||||||
|
if (loginHandler != null) {
|
||||||
|
try {
|
||||||
|
loginHandler.handle(loginUser);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.error(e.getMessage(), e);
|
||||||
|
throw new UserAuthenticationException("登录异常");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package cn.com.tenlion.operator.login.phone.auth;
|
||||||
|
|
||||||
|
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public class LoginPhoneAuthToken extends AbstractAuthenticationToken {
|
||||||
|
|
||||||
|
private final Object principal;
|
||||||
|
private Object credentials;
|
||||||
|
|
||||||
|
public LoginPhoneAuthToken(Object principal, Object credentials) {
|
||||||
|
super(null);
|
||||||
|
this.principal = principal;
|
||||||
|
this.credentials = credentials;
|
||||||
|
setAuthenticated(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LoginPhoneAuthToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) {
|
||||||
|
super(authorities);
|
||||||
|
this.principal = principal;
|
||||||
|
this.credentials = credentials;
|
||||||
|
setAuthenticated(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getCredentials() {
|
||||||
|
return credentials;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getPrincipal() {
|
||||||
|
return principal;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -288,7 +288,6 @@
|
|||||||
}
|
}
|
||||||
#loginBox .denglu .yzmtx1 {
|
#loginBox .denglu .yzmtx1 {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: none;
|
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 38px;
|
height: 38px;
|
||||||
@ -306,7 +305,6 @@
|
|||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
#loginBox .denglu .yzmbox1 {
|
#loginBox .denglu .yzmbox1 {
|
||||||
display: none;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 38px;
|
height: 38px;
|
||||||
line-height: 38px;
|
line-height: 38px;
|
||||||
@ -404,11 +402,11 @@
|
|||||||
<div id="loginBox" class="layadmin-user-login-main">
|
<div id="loginBox" class="layadmin-user-login-main">
|
||||||
<div class="btnlist">
|
<div class="btnlist">
|
||||||
<div>
|
<div>
|
||||||
<button id="zhanghaomima">账号密码</button>
|
<button id="zhanghaomima" @click="loginTypeChange('zhanghaomima')">账号密码</button>
|
||||||
<span class="span1"></span>
|
<span class="span1"></span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button id="yzmlongin">验证码登录</button>
|
<button id="yzmlongin" @click="loginTypeChange('yanzhengma')">验证码登录</button>
|
||||||
<span class="span2"></span>
|
<span class="span2"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -425,22 +423,22 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="loginFormBox" class="layadmin-user-login-box layadmin-user-login-body layui-form">
|
<div id="loginFormBox" class="layadmin-user-login-box layadmin-user-login-body layui-form">
|
||||||
<form id="loginForm" :action="pageParams.loginFormAction" method="post" @submit.prevent="submitForm" class="denglu">
|
<form id="loginForm" :action="activeAction" method="post" @submit.prevent="submitForm" class="denglu">
|
||||||
<input type="hidden" name="referToken" v-model="formData.referToken"/>
|
<input type="hidden" name="referToken" v-model="formData.referToken"/>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layadmin-user-login-icon layui-icon layui-icon-username" for="username"></label>
|
<label class="layadmin-user-login-icon layui-icon layui-icon-username" for="username"></label>
|
||||||
<input type="text" v-model="formData.username" id="username" name="username" lay-verify="username" placeholder="用户名" class="layui-input">
|
<input type="text" v-model="formData.username" id="username" name="username" lay-verify="username" placeholder="用户名" class="layui-input">
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item mima" id="passwordBox" >
|
<div class="layui-form-item mima" id="passwordBox" v-if="loginType === 'zhanghaomima'">
|
||||||
<label class="layadmin-user-login-icon layui-icon layui-icon-password" for="password"></label>
|
<label class="layadmin-user-login-icon layui-icon layui-icon-password" for="password"></label>
|
||||||
<input type="password" v-model="formData.password" id="password" name="password" lay-verify="password" placeholder="密码" class="layui-input">
|
<input type="password" v-model="formData.password" id="password" name="password" lay-verify="password" placeholder="密码" class="layui-input">
|
||||||
</div>
|
</div>
|
||||||
<div class="yzmbox1" @click="getLoginVerificationCode">
|
<div class="yzmbox1" @click="getLoginVerificationCode" v-if="loginType === 'yanzhengma'">
|
||||||
<span id="yzm11">点击获取验证码</span>
|
<span id="yzm11">点击获取验证码</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="yzmtx1">
|
<div class="yzmtx1" v-if="loginType === 'yanzhengma'">
|
||||||
<label class="layadmin-user-login-icon layui-icon layui-icon-password" for="password"></label>
|
<label class="layadmin-user-login-icon layui-icon layui-icon-password" for="inputyzm11"></label>
|
||||||
<input type="text" placeholder="请输入验证码" id="inputyzm11">
|
<input type="text" v-model="formData.code" name="code" placeholder="请输入验证码" lay-verify="code" id="inputyzm11">
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item" id="verificationCodeBox" v-if="pageParams.verificationCode == 'true'" >
|
<div class="layui-form-item" id="verificationCodeBox" v-if="pageParams.verificationCode == 'true'" >
|
||||||
<!-- 验证码 -->
|
<!-- 验证码 -->
|
||||||
@ -525,6 +523,8 @@
|
|||||||
el: '#app',
|
el: '#app',
|
||||||
data: {
|
data: {
|
||||||
pageParams: pageParams,
|
pageParams: pageParams,
|
||||||
|
loginType: 'zhanghaomima',
|
||||||
|
activeAction: pageParams.loginFormAction,
|
||||||
formData: {
|
formData: {
|
||||||
referToken: pageParams.referToken,
|
referToken: pageParams.referToken,
|
||||||
verificationCode: '',
|
verificationCode: '',
|
||||||
@ -680,7 +680,15 @@
|
|||||||
$('#loginForm').submit();
|
$('#loginForm').submit();
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
loginTypeChange: function(type) {
|
||||||
|
if(type === 'zhanghaomima') {
|
||||||
|
this.activeAction = this.pageParams.loginFormAction;
|
||||||
|
}
|
||||||
|
if(type === 'yanzhengma') {
|
||||||
|
this.activeAction = this.pageParams.loginPhoneAction;
|
||||||
|
}
|
||||||
|
this.loginType = type;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
mounted: function() {
|
mounted: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -703,6 +711,11 @@
|
|||||||
return '密码不能为空';
|
return '密码不能为空';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
code: function(value, item) {
|
||||||
|
if(!value) {
|
||||||
|
return '验证码不能为空';
|
||||||
|
}
|
||||||
|
},
|
||||||
verificationCode: function(value, item) {
|
verificationCode: function(value, item) {
|
||||||
if(!value) {
|
if(!value) {
|
||||||
return '验证码不能为空';
|
return '验证码不能为空';
|
||||||
@ -713,6 +726,7 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 切换账号密码登录和验证码登录
|
// 切换账号密码登录和验证码登录
|
||||||
|
let loginForm = document.querySelector("#loginForm");
|
||||||
let mima = document.querySelector(".mima")
|
let mima = document.querySelector(".mima")
|
||||||
let yzmbox1 = document.querySelector('.yzmbox1')
|
let yzmbox1 = document.querySelector('.yzmbox1')
|
||||||
let yzmtx1 = document.querySelector(".yzmtx1")
|
let yzmtx1 = document.querySelector(".yzmtx1")
|
||||||
@ -731,10 +745,7 @@
|
|||||||
span2.style.display = 'none'
|
span2.style.display = 'none'
|
||||||
yzmlongin.style.fontWeight = 400
|
yzmlongin.style.fontWeight = 400
|
||||||
yzmlongin.style.borderBottom = '0'
|
yzmlongin.style.borderBottom = '0'
|
||||||
mima.style.display = 'block'
|
|
||||||
bixuan.style.display = 'block'
|
bixuan.style.display = 'block'
|
||||||
yzmtx1.style.display = 'none'
|
|
||||||
yzmbox1.style.display = 'none'
|
|
||||||
})
|
})
|
||||||
// 验证码登录
|
// 验证码登录
|
||||||
document.querySelector('#yzmlongin').addEventListener('click', function () {
|
document.querySelector('#yzmlongin').addEventListener('click', function () {
|
||||||
@ -744,10 +755,7 @@
|
|||||||
span2.style.display = 'block'
|
span2.style.display = 'block'
|
||||||
zhanghaomima.style.fontWeight = 400
|
zhanghaomima.style.fontWeight = 400
|
||||||
zhanghaomima.style.borderBottom = '0'
|
zhanghaomima.style.borderBottom = '0'
|
||||||
mima.style.display = 'none'
|
|
||||||
bixuan.style.display = 'none'
|
bixuan.style.display = 'none'
|
||||||
yzmtx1.style.display = 'block'
|
|
||||||
yzmbox1.style.display = 'block'
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// 点击 忘记密码 去登录 切换div
|
// 点击 忘记密码 去登录 切换div
|
||||||
@ -761,14 +769,10 @@
|
|||||||
|
|
||||||
// 忘记密码
|
// 忘记密码
|
||||||
document.querySelector('#goChangePassword').addEventListener('click', function () {
|
document.querySelector('#goChangePassword').addEventListener('click', function () {
|
||||||
|
|
||||||
btnList.style.display = 'none'
|
btnList.style.display = 'none'
|
||||||
change.style.display = 'block'
|
change.style.display = 'block'
|
||||||
dengLu.style.display = 'none'
|
dengLu.style.display = 'none'
|
||||||
changePassword.style.display = 'block'
|
changePassword.style.display = 'block'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// 去登录
|
// 去登录
|
||||||
|
Loading…
Reference in New Issue
Block a user