publish 0.0.5
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
package com.tiesheng.login;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import com.tiesheng.platform.PlatformAutoImportSelector;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* @author hao
|
||||
@@ -10,6 +11,6 @@ import org.springframework.context.annotation.ComponentScan;
|
||||
@ComponentScan({
|
||||
"com.tiesheng.login.**.*",
|
||||
})
|
||||
@MapperScan("com.tiesheng.login.mapper")
|
||||
@Import(PlatformAutoImportSelector.class)
|
||||
public class LoginAutoImportSelector {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.tiesheng.login.config;
|
||||
|
||||
import com.tiesheng.login.config.token.bean.TokenBean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @author hao
|
||||
*/
|
||||
@Configuration
|
||||
public interface TieshengLoginConfigurer {
|
||||
|
||||
/**
|
||||
* 执行登录
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
TokenBean doLogin(String appId, String uniqueId, String platfrom, String info);
|
||||
|
||||
|
||||
/**
|
||||
* 授权登录回调
|
||||
*
|
||||
* @param tokenBean
|
||||
*/
|
||||
void onLoginRedirect(TokenBean bean, String extra, HttpServletResponse response);
|
||||
|
||||
|
||||
}
|
||||
@@ -62,19 +62,6 @@ public class TsTokenConfig {
|
||||
return ignores.get(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置token
|
||||
*/
|
||||
public String toToken(String id, String environmentType, String service, String extra) {
|
||||
return JWT.create()
|
||||
.setPayload("id", id)
|
||||
.setPayload("environmentType", environmentType)
|
||||
.setPayload("service", service)
|
||||
.setPayload("extra", extra)
|
||||
.setPayload("time", System.currentTimeMillis() + expireHours * 1000 * 60 * 60)
|
||||
.setKey(getEncryptKey().getBytes())
|
||||
.sign();
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证token
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package com.tiesheng.login.config.token.bean;
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import cn.hutool.jwt.JWT;
|
||||
import com.tiesheng.login.config.token.TsTokenConfig;
|
||||
|
||||
/**
|
||||
* @author hao
|
||||
*/
|
||||
@@ -20,6 +24,22 @@ public class TokenBean {
|
||||
this.extra = "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置token
|
||||
*/
|
||||
public String toToken() {
|
||||
TsTokenConfig tsTokenConfig = SpringUtil.getBean(TsTokenConfig.class);
|
||||
return JWT.create()
|
||||
.setPayload("id", getId())
|
||||
.setPayload("environmentType", getEnvironmentType())
|
||||
.setPayload("service", getService())
|
||||
.setPayload("extra", getExtra())
|
||||
.setPayload("time", System.currentTimeMillis() + tsTokenConfig.getExpireHours() * 1000 * 60 * 60)
|
||||
.setKey(tsTokenConfig.getEncryptKey().getBytes())
|
||||
.sign();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// setter\getter
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
package com.tiesheng.login.controller;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.tiesheng.annotation.token.TokenIgnore;
|
||||
import com.tiesheng.login.config.token.TsTokenConfig;
|
||||
import com.tiesheng.login.config.token.bean.TokenBean;
|
||||
import com.tiesheng.login.pojos.dto.UniqueIndexDTO;
|
||||
import com.tiesheng.login.service.LoginService;
|
||||
import com.tiesheng.platform.config.ding.PlatformDingConfig;
|
||||
import com.tiesheng.platform.config.ding.bean.DingJsapiSignature;
|
||||
import com.tiesheng.platform.config.ding.bean.DingUserInfo;
|
||||
import com.tiesheng.platform.config.wxmp.PlatformWxmpConfig;
|
||||
import com.tiesheng.platform.config.wxmp.bean.WxJsapiSignature;
|
||||
import com.tiesheng.platform.config.wxmp.bean.WxUserInfo;
|
||||
import com.tiesheng.util.exception.ApiException;
|
||||
import com.tiesheng.util.pojos.ApiResp;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* @author hao
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/login")
|
||||
public class LoginController {
|
||||
|
||||
|
||||
@Autowired
|
||||
PlatformWxmpConfig platformWxmpConfig;
|
||||
@Autowired
|
||||
PlatformDingConfig platformDingConfig;
|
||||
@Autowired
|
||||
LoginService loginService;
|
||||
@Autowired
|
||||
TsTokenConfig tsTokenConfig;
|
||||
|
||||
|
||||
/**
|
||||
* 唯一值登录方式,如学号,手机号等
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/unique/redirect")
|
||||
@TokenIgnore
|
||||
public void uniqueIndex(UniqueIndexDTO dto, HttpServletResponse response) {
|
||||
loginService.checkLoginConfigurer(s -> {
|
||||
TokenBean tokenBean = s.doLogin("unique_index_" + dto.getPlatform(),
|
||||
dto.getNo(), dto.getPlatform(), dto.getInfo());
|
||||
s.onLoginRedirect(tokenBean, dto.getExtra(), response);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 授权登录
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/unique/index")
|
||||
@TokenIgnore
|
||||
public ApiResp<String> uniqueIndex(@RequestBody UniqueIndexDTO dto) {
|
||||
AtomicReference<TokenBean> tokenBeanAtomicReference = new AtomicReference<>();
|
||||
loginService.checkLoginConfigurer(s -> {
|
||||
tokenBeanAtomicReference.set(s.doLogin("unique_index_" + dto.getPlatform(),
|
||||
dto.getNo(), dto.getPlatform(), dto.getInfo()));
|
||||
});
|
||||
TokenBean tokenBean = tokenBeanAtomicReference.get();
|
||||
if (tokenBean == null) {
|
||||
throw new ApiException("登录失败");
|
||||
}
|
||||
return ApiResp.respOK(tokenBean.toToken());
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// 钉钉相关授权
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* 钉钉授权登录
|
||||
*
|
||||
* @param service
|
||||
* @param extra
|
||||
* @param response
|
||||
*/
|
||||
@GetMapping("/ding/index/{service}")
|
||||
@TokenIgnore
|
||||
public void dingIndex(@PathVariable String service, String extra, HttpServletResponse response) {
|
||||
if (StrUtil.isEmpty(extra)) {
|
||||
extra = "";
|
||||
}
|
||||
Map<String, String> map = MapUtil.newHashMap();
|
||||
map.put("corpId", platformDingConfig.getConfigBean(service).getCorpId());
|
||||
map.put("service", service);
|
||||
map.put("extra", extra);
|
||||
loginService.checkLoginConfigurer(s -> {
|
||||
String query = URLUtil.buildQuery(map, Charset.defaultCharset());
|
||||
String configUrl = loginService.buildPath("/ding/index.html?" + query);
|
||||
try {
|
||||
response.sendRedirect(configUrl);
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 钉钉授权回调
|
||||
*
|
||||
* @param service
|
||||
*/
|
||||
@RequestMapping("/ding/oauth2/{service}")
|
||||
@TokenIgnore
|
||||
public void dingOauth2(@PathVariable String service, String code, String extra, HttpServletResponse response) {
|
||||
loginService.checkLoginConfigurer(configurer -> {
|
||||
String ddUserId = platformDingConfig.getUserIdByCode(service, code);
|
||||
DingUserInfo dingUserInfo = platformDingConfig.topapiV2UserGet(service, ddUserId);
|
||||
TokenBean tokenBean = configurer.doLogin(dingUserInfo.getAppId(), dingUserInfo.getUserid(), "ding",
|
||||
JSON.toJSONString(dingUserInfo));
|
||||
configurer.onLoginRedirect(tokenBean, extra, response);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 钉钉授权jssdk
|
||||
*
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/ding/jssdk/{service}")
|
||||
@TokenIgnore
|
||||
public ApiResp<DingJsapiSignature> dingJssdk(@PathVariable String service, String url) {
|
||||
DingJsapiSignature jsapiSignature = platformDingConfig.createJsapiSignature(service, url);
|
||||
return ApiResp.respOK(jsapiSignature);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// 微信相关
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* 微信授权登录
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping("/wxmp/index/{service}")
|
||||
@TokenIgnore
|
||||
public void wxmpIndex(@PathVariable String service, String extra, HttpServletResponse response) throws IOException {
|
||||
if (StrUtil.isEmpty(extra)) {
|
||||
extra = "";
|
||||
}
|
||||
String configUrl = loginService.buildPath("/auth/wxmp/oauth2/" + service + "?extra=" + extra);
|
||||
String authorizationUrl = platformWxmpConfig.buildAuthorizationUrl(service, configUrl, "snsapi_userinfo");
|
||||
response.sendRedirect(authorizationUrl);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 微信授权回调
|
||||
*
|
||||
* @param code
|
||||
*/
|
||||
@RequestMapping("/wxmp/oauth2/{service}")
|
||||
@TokenIgnore
|
||||
public void wxmpOauth2(@PathVariable String service, String code, String extra, HttpServletResponse response) {
|
||||
loginService.checkLoginConfigurer(configurer -> {
|
||||
WxUserInfo wxUserInfo = platformWxmpConfig.getOAuth2AccessToken(service, code);
|
||||
TokenBean tokenBean = configurer.doLogin(wxUserInfo.getAppId(), wxUserInfo.getOpenid(), "wxmp", JSON.toJSONString(wxUserInfo));
|
||||
configurer.onLoginRedirect(tokenBean, extra, response);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 微信授权jssdk
|
||||
*
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/wxmp/jssdk/{service}")
|
||||
@TokenIgnore
|
||||
public ApiResp<WxJsapiSignature> wxmpJssdk(@PathVariable String service, String url) {
|
||||
WxJsapiSignature jsapiSignature = platformWxmpConfig.createJsapiSignature(service, url);
|
||||
return ApiResp.respOK(jsapiSignature);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.tiesheng.login.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author hao
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/login/user")
|
||||
public class LoginUserController {
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package com.tiesheng.login.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.tiesheng.login.pojos.dao.CoreLogLogin;
|
||||
|
||||
public interface CoreLogLoginMapper extends BaseMapper<CoreLogLogin> {
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
package com.tiesheng.login.pojos.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 日志-登录
|
||||
*/
|
||||
@TableName(value = "core_log_login")
|
||||
public class CoreLogLogin {
|
||||
|
||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||
private String id;
|
||||
|
||||
@TableField(value = "create_time", fill = FieldFill.INSERT)
|
||||
private Date createTime;
|
||||
|
||||
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
|
||||
private Date updateTime;
|
||||
|
||||
@TableField(value = "is_deleted")
|
||||
private Integer isDeleted;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
@TableField(value = "user_id")
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
@TableField(value = "user_name")
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* ip
|
||||
*/
|
||||
@TableField(value = "platform")
|
||||
private String platform;
|
||||
|
||||
/**
|
||||
* ip
|
||||
*/
|
||||
@TableField(value = "ip")
|
||||
private String ip;
|
||||
|
||||
/**
|
||||
* ip地址
|
||||
*/
|
||||
@TableField(value = "address")
|
||||
private String address;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public Date getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(Date updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
|
||||
public Integer getIsDeleted() {
|
||||
return isDeleted;
|
||||
}
|
||||
|
||||
public void setIsDeleted(Integer isDeleted) {
|
||||
this.isDeleted = isDeleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户id
|
||||
*
|
||||
* @return user_id - 用户id
|
||||
*/
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置用户id
|
||||
*
|
||||
* @param userId 用户id
|
||||
*/
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public String getPlatform() {
|
||||
return platform;
|
||||
}
|
||||
|
||||
public void setPlatform(String platform) {
|
||||
this.platform = platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取ip
|
||||
*
|
||||
* @return ip - ip
|
||||
*/
|
||||
public String getIp() {
|
||||
return ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置ip
|
||||
*
|
||||
* @param ip ip
|
||||
*/
|
||||
public void setIp(String ip) {
|
||||
this.ip = ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取ip地址
|
||||
*
|
||||
* @return address - ip地址
|
||||
*/
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置ip地址
|
||||
*
|
||||
* @param address ip地址
|
||||
*/
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.tiesheng.login.pojos.dto;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
public class UniqueIndexDTO {
|
||||
|
||||
private String no;
|
||||
private String platform;
|
||||
private String extra;
|
||||
private String info;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// setter\getter
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public String getNo() {
|
||||
return no;
|
||||
}
|
||||
|
||||
public void setNo(String no) {
|
||||
this.no = no;
|
||||
}
|
||||
|
||||
public String getPlatform() {
|
||||
return platform;
|
||||
}
|
||||
|
||||
public void setPlatform(String platform) {
|
||||
this.platform = platform;
|
||||
}
|
||||
|
||||
public String getExtra() {
|
||||
if (StrUtil.isEmpty(extra)) {
|
||||
extra = "";
|
||||
}
|
||||
return extra;
|
||||
}
|
||||
|
||||
public void setExtra(String extra) {
|
||||
this.extra = extra;
|
||||
}
|
||||
|
||||
public String getInfo() {
|
||||
return info;
|
||||
}
|
||||
|
||||
public void setInfo(String info) {
|
||||
this.info = info;
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package com.tiesheng.login.service;
|
||||
|
||||
import cn.hutool.extra.servlet.ServletUtil;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.tiesheng.login.mapper.CoreLogLoginMapper;
|
||||
import com.tiesheng.login.pojos.dao.CoreLogLogin;
|
||||
import com.tiesheng.util.ServletKit;
|
||||
import com.tiesheng.util.ip2region.DataBlock;
|
||||
import com.tiesheng.util.ip2region.Ip2Region;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* @author hao
|
||||
*/
|
||||
@Service
|
||||
public class LoginLogService extends ServiceImpl<CoreLogLoginMapper, CoreLogLogin> {
|
||||
|
||||
|
||||
/**
|
||||
* 获取
|
||||
*
|
||||
* @param userId
|
||||
*/
|
||||
public void addLog(String userId, String platform) {
|
||||
|
||||
HttpServletRequest request = ServletKit.getRequest();
|
||||
String ip = ServletUtil.getClientIP(request);
|
||||
|
||||
CoreLogLogin login = new CoreLogLogin();
|
||||
login.setUserId(userId);
|
||||
login.setPlatform(platform);
|
||||
|
||||
login.setIp(ip);
|
||||
DataBlock dataBlock = Ip2Region.getInstance().btreeSearch(ip);
|
||||
login.setAddress(dataBlock.getRegion());
|
||||
save(login);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.tiesheng.login.service;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import com.tiesheng.login.config.TieshengLoginConfigurer;
|
||||
import com.tiesheng.util.exception.ApiException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* @author hao
|
||||
*/
|
||||
@Service
|
||||
public class LoginService {
|
||||
|
||||
@Value("${tiesheng.global.host}")
|
||||
String globalHost;
|
||||
@Autowired(required = false)
|
||||
TieshengLoginConfigurer tieshengLoginConfigurer;
|
||||
|
||||
|
||||
/**
|
||||
* 检查配置
|
||||
*/
|
||||
public void checkLoginConfigurer(Consumer<TieshengLoginConfigurer> consumer) {
|
||||
if (tieshengLoginConfigurer == null) {
|
||||
throw new ApiException("未配置登录逻辑");
|
||||
}
|
||||
consumer.accept(tieshengLoginConfigurer);
|
||||
}
|
||||
|
||||
public String getContextPath() {
|
||||
String context = SpringUtil.getProperty("server.servlet.context-path");
|
||||
if (StrUtil.isEmpty(context)) {
|
||||
context = "";
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
public String buildPath(String path) {
|
||||
if (StrUtil.isEmpty(path)) {
|
||||
path = "";
|
||||
}
|
||||
|
||||
if (!StrUtil.isEmpty(this.globalHost) && !StrUtil.startWith(path, "http")) {
|
||||
path = this.globalHost + this.getContextPath() + path;
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user