7.17 通过浏览器指纹获取ticket + 无痕登录

This commit is contained in:
zhangsan 2025-07-17 14:43:08 +08:00
parent b235462189
commit 3df396437b
7 changed files with 83 additions and 4 deletions

View File

@ -6,6 +6,10 @@ public interface IAuthService {
Response<String> weixinQrCodeTicket();
Response<String> weixinQrCodeTicket(String sceneStr);
Response<String> checkLogin(String ticket);
Response<String> checkLogin(String ticket, String sceneStr);
}

View File

@ -6,6 +6,8 @@ public interface ILoginPort {
String createQrCodeTicket() throws IOException;
String createQrCodeTicket(String sceneStr) throws IOException;
void sendLoginTemplate(String openid) throws IOException;
}

View File

@ -6,9 +6,13 @@ public interface ILoginService {
String createQrCodeTicket() throws Exception;
String createQrCodeTicket(String sceneStr) throws Exception;
String checkLogin(String ticket);
String checkLogin(String ticket, String sceneStr);
void saveLoginState(String ticket, String openid) throws IOException;
}

View File

@ -3,9 +3,9 @@ import com.google.common.cache.Cache;
import edu.whut.domain.auth.adapter.port.ILoginPort;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.IOException;
@Slf4j
@ -26,6 +26,14 @@ public class WeixinLoginService implements ILoginService {
return loginPort.createQrCodeTicket();
}
@Override
public String createQrCodeTicket(String sceneStr) throws Exception {
String ticket = loginPort.createQrCodeTicket(sceneStr);
// 保存浏览器指纹信息和ticket映射关系
openidToken.put(sceneStr, ticket);
return ticket;
}
/**
* 检查扫码登录状态
* 根据前端传回的 ticket轮询或查询登录结果
@ -36,6 +44,13 @@ public class WeixinLoginService implements ILoginService {
return openidToken.getIfPresent(ticket);
}
@Override
public String checkLogin(String ticket, String sceneStr) {
String cacheTicket = openidToken.getIfPresent(sceneStr);
if (StringUtils.isBlank(cacheTicket) || !cacheTicket.equals(ticket)) return null;
return checkLogin(ticket);
}
/**
* 保存登录状态
* 将用户的登录态ticket openid 的映射持久化或缓存

View File

@ -30,6 +30,10 @@
<groupId>com.squareup.retrofit2</groupId>
<artifactId>adapter-rxjava2</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>edu.whut</groupId>
<artifactId>group-buying-sys-api</artifactId>

View File

@ -8,8 +8,6 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@Slf4j
@RestController()
@CrossOrigin("*")
@ -43,6 +41,26 @@ public class LoginController implements IAuthService {
}
}
@GetMapping("/weixin_qrcode_ticket_scene")
@Override
public Response<String> weixinQrCodeTicket(@RequestParam String sceneStr) {
try {
String qrCodeTicket = loginService.createQrCodeTicket(sceneStr);
log.info("生成微信扫码登录 ticket:{}", qrCodeTicket);
return Response.<String>builder()
.code(Constants.ResponseCode.SUCCESS.getCode())
.info(Constants.ResponseCode.SUCCESS.getInfo())
.data(qrCodeTicket)
.build();
} catch (Exception e) {
log.error("生成微信扫码登录 ticket 失败", e);
return Response.<String>builder()
.code(Constants.ResponseCode.UN_ERROR.getCode())
.info(Constants.ResponseCode.UN_ERROR.getInfo())
.build();
}
}
/**
* 检测指定 ticket 的登录状态
* 如果用户已扫码后端已收到 openid 回调就返回对应的登录令牌 openidToken JWT
@ -50,7 +68,7 @@ public class LoginController implements IAuthService {
*/
@GetMapping("/check_login")
@Override
public Response<String> checkLogin(String ticket) {
public Response<String> checkLogin(@RequestParam String ticket) {
try {
String openidToken = loginService.checkLogin(ticket);
log.info("扫码检测登录结果 ticket:{} openidToken:{}", ticket, openidToken);
@ -75,4 +93,31 @@ public class LoginController implements IAuthService {
}
}
@GetMapping("/check_login_scene")
@Override
public Response<String> checkLogin(@RequestParam String ticket, @RequestParam String sceneStr) {
try {
String openidToken = loginService.checkLogin(ticket, sceneStr);
log.info("扫码检测登录结果 ticket:{} openidToken:{} sceneStr:{}", ticket, openidToken, sceneStr);
if (StringUtils.isNotBlank(openidToken)) {
return Response.<String>builder()
.code(Constants.ResponseCode.SUCCESS.getCode())
.info(Constants.ResponseCode.SUCCESS.getInfo())
.data(openidToken)
.build();
} else {
return Response.<String>builder()
.code(Constants.ResponseCode.NO_LOGIN.getCode())
.info(Constants.ResponseCode.NO_LOGIN.getInfo())
.build();
}
} catch (Exception e) {
log.error("扫码检测登录结果失败 ticket:{}", ticket, e);
return Response.<String>builder()
.code(Constants.ResponseCode.UN_ERROR.getCode())
.info(Constants.ResponseCode.UN_ERROR.getInfo())
.build();
}
}
}

View File

@ -136,6 +136,11 @@
<artifactId>alipay-sdk-java</artifactId>
<version>4.38.157.ALL</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.26</version>
</dependency>
<!-- 工程模块 -->
<dependency>
<groupId>edu.whut</groupId>