登录/登出接口完善

This commit is contained in:
aoshiguchen
2022-08-02 22:04:32 +08:00
parent a5a2ef8a62
commit 3467cc96d3
11 changed files with 542 additions and 20 deletions
@@ -36,7 +36,9 @@ public enum ExceptionConstant {
USER_NOT_LOGIN(1, "用户未登录"),
PARAMS_INVALID(2, "参数不正确"),
PARAMS_NOT_NULL(3, "参数[%s]不能为空"),
SYSTEM_ERROR(500, "系统异常");
USER_NAME_OR_PASSWORD_ERROR(4, "用户名或密码错误"),
SYSTEM_ERROR(500, "系统异常"),
;
private int code;
private String msg;
@@ -0,0 +1,55 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.base.rest;
import fun.asgc.neutrino.proxy.server.dal.entity.UserDO;
/**
*
* @author: aoshiguchen
* @date: 2022/8/2
*/
public class SystemContextHolder {
private static final ThreadLocal<UserDO> userHolder = new ThreadLocal<>();
private static final ThreadLocal<String> tokenHolder = new ThreadLocal<>();
public static void remove() {
userHolder.remove();
tokenHolder.remove();
}
public static void setUser(UserDO user) {
userHolder.set(user);
}
public static UserDO getUser() {
return userHolder.get();
}
public static void setToken(String token) {
tokenHolder.set(token);
}
public static String getToken() {
return tokenHolder.get();
}
}
@@ -21,9 +21,17 @@
*/
package fun.asgc.neutrino.proxy.server.base.rest.interceptor;
import fun.asgc.neutrino.core.util.BeanManager;
import fun.asgc.neutrino.core.util.StringUtil;
import fun.asgc.neutrino.core.web.context.HttpRequestWrapper;
import fun.asgc.neutrino.core.web.context.HttpResponseWrapper;
import fun.asgc.neutrino.core.web.interceptor.HandlerInterceptor;
import fun.asgc.neutrino.proxy.server.base.rest.Authorization;
import fun.asgc.neutrino.proxy.server.base.rest.ExceptionConstant;
import fun.asgc.neutrino.proxy.server.base.rest.ServiceException;
import fun.asgc.neutrino.proxy.server.base.rest.SystemContextHolder;
import fun.asgc.neutrino.proxy.server.dal.entity.UserDO;
import fun.asgc.neutrino.proxy.server.service.UserService;
import java.lang.reflect.Method;
@@ -36,8 +44,25 @@ public class BaseAuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpRequestWrapper requestParser, HttpResponseWrapper responseWrapper, String route, Method targetMethod) throws Exception {
// TODO
Authorization authorization = targetMethod.getAnnotation(Authorization.class);
if (null == authorization || authorization.login()) {
String authorize = requestParser.getHeaderValue("Authorize");
if (StringUtil.isEmpty(authorize)) {
throw ServiceException.create(ExceptionConstant.USER_NOT_LOGIN);
}
UserDO userDO = BeanManager.getBean(UserService.class).findByToken(authorize);
if (null == userDO) {
throw ServiceException.create(ExceptionConstant.USER_NOT_LOGIN);
}
SystemContextHolder.setUser(userDO);
SystemContextHolder.setToken(authorize);
}
return true;
}
@Override
public void afterCompletion(HttpRequestWrapper requestParser, HttpResponseWrapper responseWrapper, String route, Method targetMethod) {
SystemContextHolder.remove();
}
}
@@ -57,9 +57,8 @@ public class IndexController {
}
@PostMapping("logout")
public LogoutRes logout(@RequestBody LogoutReq req) {
// TODO
return null;
public void logout() {
userService.logout();
}
}
@@ -0,0 +1,43 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.dal;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.db.annotation.Insert;
import fun.asgc.neutrino.core.db.mapper.SqlMapper;
import fun.asgc.neutrino.proxy.server.dal.entity.UserLoginRecordDO;
/**
*
* @author: aoshiguchen
* @date: 2022/8/2
*/
@Component
public interface UserLoginRecordMapper extends SqlMapper {
/**
* 新增用户登录日志
* @param userLoginRecord
* @return
*/
@Insert("insert into `user_login_record`(`user_id`,`ip`,`token`,`type`,`create_time`) values(:userId,:ip,:token,:type,:createTime)")
int add(UserLoginRecordDO userLoginRecord);
}
@@ -42,4 +42,12 @@ public interface UserMapper extends SqlMapper {
@Select("select * from user where login_name = ?")
UserDO findByLoginName(String loginName);
/**
* 根据id查询单条记录
* @param id
* @return
*/
@Select("select * from user where id = ?")
UserDO findById(Integer id);
}
@@ -22,10 +22,14 @@
package fun.asgc.neutrino.proxy.server.dal;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.db.annotation.Delete;
import fun.asgc.neutrino.core.db.annotation.Insert;
import fun.asgc.neutrino.core.db.annotation.Select;
import fun.asgc.neutrino.core.db.mapper.SqlMapper;
import fun.asgc.neutrino.proxy.server.dal.entity.UserTokenDO;
import java.util.Date;
/**
*
* @author: aoshiguchen
@@ -40,4 +44,19 @@ public interface UserTokenMapper extends SqlMapper {
*/
@Insert("insert into `user_token`(`token`,`user_id`,`expiration_time`,`create_time`,`update_time`) values (:token,:userId,:expirationTime,:createTime,:updateTime)")
int add(UserTokenDO userToken);
/**
* 根据token查询单条记录
* @param token
* @return
*/
@Select("select * from user_token where token = ? and expiration_time > ?")
UserTokenDO findByAvailableToken(String token, Long time);
/**
* 根据token删除记录
* @param token
*/
@Delete("delete from user_token where token = ?")
void deleteByToken(String token);
}
@@ -0,0 +1,64 @@
/**
* Copyright (C) 2018-2022 Zeyi information technology (Shanghai) Co., Ltd.
* <p>
* All right reserved.
* <p>
* This software is the confidential and proprietary
* information of Zeyi Company of China.
* ("Confidential Information"). You shall not disclose
* such Confidential Information and shall use it only
* in accordance with the terms of the contract agreement
* you entered into with Zeyi inc.
*/
package fun.asgc.neutrino.proxy.server.dal.entity;
import fun.asgc.neutrino.core.db.annotation.Id;
import fun.asgc.neutrino.core.db.annotation.Table;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.util.Date;
/**
*
* @author: aoshiguchen
* @date: 2022/8/2
*/
@ToString
@Data
@Accessors(chain = true)
@Table("user_login_record")
public class UserLoginRecordDO {
/**
* 类型 - 登录
*/
public static final Integer TYPE_LOGIN = 1;
/**
* 类型 - 登出
*/
public static final Integer TYPE_LOGOUT = 2;
@Id
private Integer id;
/**
* 用户ID
*/
private Integer userId;
/**
* token
*/
private String token;
/**
* ip
*/
private String ip;
/**
* 类型
*/
private Integer type;
/**
* 创建时间
*/
private Date createTime;
}
@@ -23,15 +23,21 @@ package fun.asgc.neutrino.proxy.server.service;
import fun.asgc.neutrino.core.annotation.Autowired;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.web.annotation.RequestBody;
import fun.asgc.neutrino.core.util.DateUtil;
import fun.asgc.neutrino.proxy.server.base.rest.ExceptionConstant;
import fun.asgc.neutrino.proxy.server.base.rest.ServiceException;
import fun.asgc.neutrino.proxy.server.base.rest.SystemContextHolder;
import fun.asgc.neutrino.proxy.server.controller.req.LoginReq;
import fun.asgc.neutrino.proxy.server.controller.res.LoginRes;
import fun.asgc.neutrino.proxy.server.dal.UserLoginRecordMapper;
import fun.asgc.neutrino.proxy.server.dal.UserMapper;
import fun.asgc.neutrino.proxy.server.dal.UserTokenMapper;
import fun.asgc.neutrino.proxy.server.dal.entity.UserDO;
import fun.asgc.neutrino.proxy.server.dal.entity.UserLoginRecordDO;
import fun.asgc.neutrino.proxy.server.dal.entity.UserTokenDO;
import fun.asgc.neutrino.proxy.server.util.Md5Util;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;
@@ -46,25 +52,36 @@ public class UserService {
private UserMapper userMapper;
@Autowired
private UserTokenMapper userTokenMapper;
@Autowired
private UserLoginRecordMapper userLoginRecordMapper;
public LoginRes login(LoginReq req) {
UserDO userDO = userMapper.findByLoginName(req.getLoginName());
if (null == userDO || !Md5Util.encode(req.getLoginPassword()).equals(userDO.getLoginPassword())) {
// TODO 抛出异常
throw ServiceException.create(ExceptionConstant.USER_NAME_OR_PASSWORD_ERROR);
}
String token = UUID.randomUUID().toString().replaceAll("-", "");
Date now = new Date();
// TODO 计算过期时间
Date expirationTime = DateUtil.addDate(now, Calendar.HOUR, 1);
// 缓存token
userTokenMapper.add(new UserTokenDO()
.setToken(token)
.setUserId(userDO.getId())
.setExpirationTime(now)
.setExpirationTime(expirationTime)
.setCreateTime(now)
.setUpdateTime(now)
);
// TODO 新增登录日志
// 新增用户登录日志
userLoginRecordMapper.add(new UserLoginRecordDO()
.setUserId(userDO.getId())
.setIp("111")
.setToken(token)
.setType(UserLoginRecordDO.TYPE_LOGIN)
.setCreateTime(now)
);
return new LoginRes()
.setToken(token)
@@ -72,4 +89,19 @@ public class UserService {
.setUserName(userDO.getName());
}
public void logout() {
userTokenMapper.deleteByToken(SystemContextHolder.getToken());
}
public UserDO findByToken(String token) {
Date now = new Date();
UserTokenDO userTokenDO = userTokenMapper.findByAvailableToken(token, now.getTime());
if (null == userTokenDO) {
return null;
}
UserDO userDO = userMapper.findById(userTokenDO.getUserId());
// TODO 校验用户是否已被禁用
return userDO;
}
}